From 645aa27cdb6b9ba6d45f98fdee6904ade5271e82 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 17 Dec 2020 18:32:06 -0800 Subject: [PATCH] Fixed #120 (last pieces) --- .../deser/OptimizedSettableBeanProperty.java | 443 +----------------- .../deser/SettableBooleanFieldProperty.java | 17 +- .../deser/SettableBooleanMethodProperty.java | 17 +- .../deser/SettableIntFieldProperty.java | 24 +- .../deser/SettableIntMethodProperty.java | 27 +- .../deser/SettableLongFieldProperty.java | 24 +- .../deser/SettableLongMethodProperty.java | 24 +- .../deser/SettableStringFieldProperty.java | 34 +- .../deser/SettableStringMethodProperty.java | 34 +- .../afterburner/deser/TestFinalFields.java | 12 +- ...ailOnPrimitiveFromNullDeserialization.java | 9 +- .../deser/jdk/JDKScalarsDeserTest.java | 18 +- .../format/MapFormatShapeTest.java | 2 +- .../afterburner/roundtrip/BiggerDataTest.java | 12 +- .../afterburner/ser/JsonAppendTest.java | 3 +- .../deser/OptimizedSettableBeanProperty.java | 443 +----------------- .../deser/SettableBooleanProperty.java | 33 +- .../blackbird/deser/SettableIntProperty.java | 26 +- .../blackbird/deser/SettableLongProperty.java | 24 +- .../deser/SettableStringProperty.java | 35 +- .../blackbird/deser/TestFinalFields.java | 12 +- ...ailOnPrimitiveFromNullDeserialization.java | 6 +- .../filter/IgnoreCreatorProp1317Test.java | 2 +- .../blackbird/deser/jdk/JDKScalarsTest.java | 6 +- .../blackbird/format/MapFormatShapeTest.java | 2 +- .../blackbird/roundtrip/BiggerDataTest.java | 12 +- .../module/blackbird/ser/JsonAppendTest.java | 3 +- release-notes/CREDITS-2.x | 5 + release-notes/VERSION-2.x | 5 + 29 files changed, 203 insertions(+), 1111 deletions(-) diff --git a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/OptimizedSettableBeanProperty.java b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/OptimizedSettableBeanProperty.java index 08572af0..7aa3576c 100644 --- a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/OptimizedSettableBeanProperty.java +++ b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/OptimizedSettableBeanProperty.java @@ -5,14 +5,10 @@ import java.util.logging.Logger; import com.fasterxml.jackson.core.*; -import com.fasterxml.jackson.core.JsonParser.NumberType; -import com.fasterxml.jackson.core.io.NumberInput; + import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.cfg.CoercionAction; -import com.fasterxml.jackson.databind.cfg.CoercionInputShape; import com.fasterxml.jackson.databind.deser.*; import com.fasterxml.jackson.databind.deser.impl.NullsConstantProvider; -import com.fasterxml.jackson.databind.type.LogicalType; import com.fasterxml.jackson.databind.util.ClassUtil; /** @@ -176,311 +172,6 @@ protected void _reportProblem(Object bean, Object value, Throwable e) /********************************************************************** */ - protected final boolean _deserializeBoolean(JsonParser p, DeserializationContext ctxt) throws IOException - { - String text; - switch (p.currentTokenId()) { - case JsonTokenId.ID_STRING: - text = p.getText(); - break; - case JsonTokenId.ID_NUMBER_INT: - // may accept ints too, (0 == false, otherwise true) - - // call returns `null`, Boolean.TRUE or Boolean.FALSE so: - return Boolean.TRUE.equals(_checkIntToBooleanCoercion(p, ctxt, Boolean.TYPE)); - case JsonTokenId.ID_TRUE: // usually caller should have handled but: - return true; - case JsonTokenId.ID_FALSE: - return false; - case JsonTokenId.ID_NULL: // null fine for non-primitive - _verifyNullForPrimitive(ctxt); - return false; - // 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML) - case JsonTokenId.ID_START_OBJECT: - text = ctxt.extractScalarFromObject(p, null, Boolean.TYPE); - break; - case JsonTokenId.ID_START_ARRAY: - // 12-Jun-2020, tatu: For some reason calling `_deserializeFromArray()` won't work so: - if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); - final boolean parsed = _deserializeBoolean(p, ctxt); - _verifyEndArrayForSingle(p, ctxt); - return parsed; - } - // fall through - default: - return ((Boolean) ctxt.handleUnexpectedToken(Boolean.TYPE, p)).booleanValue(); - } - - final CoercionAction act = _checkFromStringCoercion(ctxt, text, - LogicalType.Boolean, Boolean.TYPE); - if (act == CoercionAction.AsNull) { - _verifyNullForPrimitive(ctxt); - return false; - } - if (act == CoercionAction.AsEmpty) { - return false; - } - text = text.trim(); - final int len = text.length(); - - // For [databind#1852] allow some case-insensitive matches (namely, - // true/True/TRUE, false/False/FALSE - if (len == 4) { - if (_isTrue(text)) { - return true; - } - } else if (len == 5) { - if (_isFalse(text)) { - return false; - } - } - if (_hasTextualNull(text)) { - _verifyNullForPrimitiveCoercion(ctxt, text); - return false; - } - Boolean b = (Boolean) ctxt.handleWeirdStringValue(Boolean.TYPE, text, - "only \"true\"/\"True\"/\"TRUE\" or \"false\"/\"False\"/\"FALSE\" recognized"); - return Boolean.TRUE.equals(b); - } - - // 16-Dec-2020, tatu: Copied from "StdDeserializer._parseIntPrimitive()" verbatim: - // - // @since 2.12.1 - protected final int _deserializeInt(JsonParser p, DeserializationContext ctxt) - throws IOException - { - String text; - switch (p.currentTokenId()) { - case JsonTokenId.ID_STRING: - text = p.getText(); - break; - case JsonTokenId.ID_NUMBER_FLOAT: - final CoercionAction act = _checkFloatToIntCoercion(p, ctxt, Integer.TYPE); - if (act == CoercionAction.AsNull) { - return 0; - } - if (act == CoercionAction.AsEmpty) { - return 0; - } - return p.getValueAsInt(); - case JsonTokenId.ID_NUMBER_INT: - return p.getIntValue(); - case JsonTokenId.ID_NULL: - _verifyNullForPrimitive(ctxt); - return 0; - // 16-Dec-2020, tatu: not sure if this will work (no deserializer to pass), - // but we'll do our best - case JsonTokenId.ID_START_OBJECT: - text = ctxt.extractScalarFromObject(p, /* deserializer */ null, Integer.TYPE); - break; - case JsonTokenId.ID_START_ARRAY: - if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); - final int parsed = _deserializeInt(p, ctxt); - _verifyEndArrayForSingle(p, ctxt); - return parsed; - } - // fall through to fail - default: - return ((Number) ctxt.handleUnexpectedToken(getType(), p)).intValue(); - } - - final CoercionAction act = _checkFromStringCoercion(ctxt, text, - LogicalType.Integer, Integer.TYPE); - if (act == CoercionAction.AsNull) { - return 0; // no need to check as does not come from `null`, explicit coercion - } - if (act == CoercionAction.AsEmpty) { - return 0; - } - text = text.trim(); - if (_hasTextualNull(text)) { - _verifyNullForPrimitiveCoercion(ctxt, text); - return 0; - } - return _parseIntPrimitive(ctxt, text); - } - - private final int _parseIntPrimitive(DeserializationContext ctxt, String text) throws IOException - { - try { - if (text.length() > 9) { - long l = Long.parseLong(text); - if (_intOverflow(l)) { - Number v = (Number) ctxt.handleWeirdStringValue(Integer.TYPE, text, - "Overflow: numeric value (%s) out of range of int (%d -%d)", - text, Integer.MIN_VALUE, Integer.MAX_VALUE); - return _nonNullNumber(v).intValue(); - } - return (int) l; - } - return NumberInput.parseInt(text); - } catch (IllegalArgumentException iae) { - Number v = (Number) ctxt.handleWeirdStringValue(Integer.TYPE, text, - "not a valid `int` value"); - return _nonNullNumber(v).intValue(); - } - } - - // 16-Dec-2020, tatu: Copied from "StdDeserializer._parseLongPrimitive()" verbatim: - // - // @since 2.12.1 - protected final long _deserializeLong(JsonParser p, DeserializationContext ctxt) - throws IOException - { - String text; - switch (p.currentTokenId()) { - case JsonTokenId.ID_STRING: - text = p.getText(); - break; - case JsonTokenId.ID_NUMBER_FLOAT: - final CoercionAction act = _checkFloatToIntCoercion(p, ctxt, Long.TYPE); - if (act == CoercionAction.AsNull) { - return 0; - } - if (act == CoercionAction.AsEmpty) { - return 0; - } - return p.getValueAsInt(); - case JsonTokenId.ID_NUMBER_INT: - return p.getIntValue(); - case JsonTokenId.ID_NULL: - _verifyNullForPrimitive(ctxt); - return 0; - // 16-Dec-2020, tatu: not sure if this will work (no deserializer to pass), - // but we'll do our best - case JsonTokenId.ID_START_OBJECT: - text = ctxt.extractScalarFromObject(p, /* deserializer */ null, Long.TYPE); - break; - case JsonTokenId.ID_START_ARRAY: - if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); - final long parsed = _deserializeLong(p, ctxt); - _verifyEndArrayForSingle(p, ctxt); - return parsed; - } - // fall through to fail - default: - return ((Number) ctxt.handleUnexpectedToken(getType(), p)).intValue(); - } - - final CoercionAction act = _checkFromStringCoercion(ctxt, text, - LogicalType.Integer, Long.TYPE); - if (act == CoercionAction.AsNull) { - return 0; // no need to check as does not come from `null`, explicit coercion - } - if (act == CoercionAction.AsEmpty) { - return 0; - } - text = text.trim(); - if (_hasTextualNull(text)) { - _verifyNullForPrimitiveCoercion(ctxt, text); - return 0; - } - return _parseLongPrimitive(ctxt, text); - } - - private final long _parseLongPrimitive(DeserializationContext ctxt, String text) throws IOException - { - try { - return NumberInput.parseLong(text); - } catch (IllegalArgumentException iae) { } - { - Number v = (Number) ctxt.handleWeirdStringValue(Long.TYPE, text, - "not a valid `long` value"); - return _nonNullNumber(v).longValue(); - } - } - - protected final String _deserializeString(JsonParser p, DeserializationContext ctxt) throws IOException - { - switch (p.currentTokenId()) { - case JsonTokenId.ID_STRING: - return p.getText(); - case JsonTokenId.ID_NULL: - return null; - case JsonTokenId.ID_START_ARRAY: - if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); - final String parsed = _deserializeString(p, ctxt); - if (p.nextToken() != JsonToken.END_ARRAY) { - _handleMissingEndArrayForSingle(p, ctxt); - } - return parsed; - } - break; - case JsonTokenId.ID_EMBEDDED_OBJECT: - Object ob = p.getEmbeddedObject(); - if (ob == null) { - return null; - } - if (ob instanceof byte[]) { - return Base64Variants.getDefaultVariant().encode((byte[]) ob, false); - } - // otherwise, try conversion using toString()... - return ob.toString(); - default: - // allow coercions for other scalar types - String text = p.getValueAsString(); - if (text != null) { - return text; - } - } - return (String) ctxt.handleUnexpectedToken(getType(), p); - } - - // // More helper methods from StdDeserializer - - private boolean _hasTextualNull(String value) { - return "null".equals(value); - } - - // [databind#1852] - private boolean _isTrue(String text) { - char c = text.charAt(0); - if (c == 't') { - return "true".equals(text); - } - if (c == 'T') { - return "TRUE".equals(text) || "True".equals(text); - } - return false; - } - - private boolean _isFalse(String text) { - char c = text.charAt(0); - if (c == 'f') { - return "false".equals(text); - } - if (c == 'F') { - return "FALSE".equals(text) || "False".equals(text); - } - return false; - } - - private final boolean _intOverflow(long value) { - return (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE); - } - - private Number _nonNullNumber(Number n) { - if (n == null) { - n = Integer.valueOf(0); - } - return n; - } - - private final static boolean _isBlank(String text) - { - final int len = text.length(); - for (int i = 0; i < len; ++i) { - if (text.charAt(i) > 0x0020) { - return false; - } - } - return true; - } - /** * Helper method used to check whether given deserializer is the default * deserializer implementation: this is necessary to avoid overriding custom @@ -491,136 +182,4 @@ protected boolean _isDefaultDeserializer(JsonDeserializer deser) { || (deser instanceof SuperSonicBeanDeserializer) || ClassUtil.isJacksonStdImpl(deser); } - - private void _verifyEndArrayForSingle(JsonParser p, DeserializationContext ctxt) throws IOException - { - JsonToken t = p.nextToken(); - if (t != JsonToken.END_ARRAY) { - _handleMissingEndArrayForSingle(p, ctxt); - } - } - - private void _handleMissingEndArrayForSingle(JsonParser p, DeserializationContext ctxt) - throws IOException - { - JavaType type = getType(); - ctxt.reportWrongTokenException(type, JsonToken.END_ARRAY, -"Attempted to unwrap single value array for single %s value but there was more than a single value in the array", -getType()); - // 05-May-2016, tatu: Should recover somehow (maybe skip until END_ARRAY); - // but for now just fall through - } - - /* - /********************************************************************** - /* New methods in 2.12.1 to align CoercionConfig handling with databind - /* (copied from "StdDeserializer") - /********************************************************************** - */ - - private CoercionAction _checkFloatToIntCoercion(JsonParser p, DeserializationContext ctxt, - Class rawTargetType) - throws IOException - { - final CoercionAction act = ctxt.findCoercionAction(LogicalType.Integer, - rawTargetType, CoercionInputShape.Float); - if (act == CoercionAction.Fail) { - return _checkCoercionFail(ctxt, act, rawTargetType, p.getNumberValue(), - "Floating-point value ("+p.getText()+")"); - } - return act; - } - - private Boolean _checkIntToBooleanCoercion(JsonParser p, DeserializationContext ctxt, - Class rawTargetType) - throws IOException - { - CoercionAction act = ctxt.findCoercionAction(LogicalType.Boolean, rawTargetType, CoercionInputShape.Integer); - switch (act) { - case Fail: - _checkCoercionFail(ctxt, act, rawTargetType, p.getNumberValue(), - "Integer value ("+p.getText()+")"); - return Boolean.FALSE; - case AsNull: - return null; - case AsEmpty: - return Boolean.FALSE; - default: - } - // 13-Oct-2016, tatu: As per [databind#1324], need to be careful wrt - // degenerate case of huge integers, legal in JSON. - // Also note that number tokens can not have WS to trim: - if (p.getNumberType() == NumberType.INT) { - // but minor optimization for common case is possible: - return p.getIntValue() != 0; - } - return !"0".equals(p.getText()); - } - - private CoercionAction _checkFromStringCoercion(DeserializationContext ctxt, String value, - LogicalType logicalType, Class rawTargetType) - throws IOException - { - final CoercionAction act; - - if (value.isEmpty()) { - act = ctxt.findCoercionAction(logicalType, rawTargetType, - CoercionInputShape.EmptyString); - return _checkCoercionFail(ctxt, act, rawTargetType, value, - "empty String (\"\")"); - } else if (_isBlank(value)) { - act = ctxt.findCoercionFromBlankString(logicalType, rawTargetType, CoercionAction.Fail); - return _checkCoercionFail(ctxt, act, rawTargetType, value, - "blank String (all whitespace)"); - } else { - act = ctxt.findCoercionAction(logicalType, rawTargetType, CoercionInputShape.String); - if (act == CoercionAction.Fail) { - // since it MIGHT (but might not), create desc here, do not use helper - ctxt.reportInputMismatch(this, -"Cannot coerce String value (\"%s\") to %s (but might if coercion using `CoercionConfig` was enabled)", -value, _coercedTypeDesc()); - } - } - return act; - } - - private CoercionAction _checkCoercionFail(DeserializationContext ctxt, - CoercionAction act, Class targetType, Object inputValue, - String inputDesc) - throws IOException - { - if (act == CoercionAction.Fail) { - // 16-Dec-2020, tatu: Let's hope `null` for deserializer is ok... - ctxt.reportBadCoercion(null, targetType, inputValue, -"Cannot coerce %s to %s (but could if coercion was enabled using `CoercionConfig`)", -inputDesc, _coercedTypeDesc()); - } - return act; - } - - private void _verifyNullForPrimitive(DeserializationContext ctxt) - throws JsonMappingException - { - if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) { - ctxt.reportInputMismatch(this, -"Cannot coerce `null` to %s (disable `DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES` to allow)", - _coercedTypeDesc()); - } - } - - private final void _verifyNullForPrimitiveCoercion(DeserializationContext ctxt, - String str) throws JsonMappingException - { - if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) { - String strDesc = str.isEmpty() ? "empty String (\"\")" : String.format("String \"%s\"", str); - ctxt.reportInputMismatch(this, -"Cannot coerce %s to %s (disable `DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES` to allow)", - strDesc, _coercedTypeDesc()); - } - } - - // Simplified as we only ever get simple scalar types - private String _coercedTypeDesc() { - return ClassUtil.getTypeDescription(getType()) +" value"; - } } diff --git a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanFieldProperty.java b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanFieldProperty.java index d2c14dec..0f95a49b 100644 --- a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanFieldProperty.java +++ b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanFieldProperty.java @@ -42,7 +42,8 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object } else if (t == JsonToken.VALUE_FALSE) { b = false; } else { - b = _deserializeBoolean(p, ctxt); + delegate.deserializeAndSet(p, ctxt, bean); + return; } try { _propertyMutator.booleanField(bean, _optimizedIndex, b); @@ -66,15 +67,13 @@ public void set(Object bean, Object value) throws IOException { public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException { - boolean b; - JsonToken t = p.getCurrentToken(); + JsonToken t = p.currentToken(); if (t == JsonToken.VALUE_TRUE) { - b = true; - } else if (t == JsonToken.VALUE_FALSE) { - b = false; - } else { - b = _deserializeBoolean(p, ctxt); + return setAndReturn(instance, Boolean.TRUE); + } + if (t == JsonToken.VALUE_FALSE) { + return setAndReturn(instance, Boolean.FALSE); } - return setAndReturn(instance, b); + return delegate.deserializeSetAndReturn(p, ctxt, instance); } } diff --git a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanMethodProperty.java b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanMethodProperty.java index a08cb7dc..772664a4 100644 --- a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanMethodProperty.java +++ b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableBooleanMethodProperty.java @@ -42,7 +42,8 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object } else if (t == JsonToken.VALUE_FALSE) { b = false; } else { - b = _deserializeBoolean(p, ctxt); + delegate.deserializeAndSet(p, ctxt, bean); + return; } try { _propertyMutator.booleanSetter(bean, _optimizedIndex, b); @@ -66,15 +67,13 @@ public void set(Object bean, Object value) throws IOException { public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException { - boolean b; - JsonToken t = p.getCurrentToken(); + JsonToken t = p.currentToken(); if (t == JsonToken.VALUE_TRUE) { - b = true; - } else if (t == JsonToken.VALUE_FALSE) { - b = false; - } else { - b = _deserializeBoolean(p, ctxt); + return setAndReturn(instance, Boolean.TRUE); + } + if (t == JsonToken.VALUE_FALSE) { + return setAndReturn(instance, Boolean.FALSE); } - return setAndReturn(instance, b); + return delegate.deserializeSetAndReturn(p, ctxt, instance); } } diff --git a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntFieldProperty.java b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntFieldProperty.java index 17f46d3d..a6af77fd 100644 --- a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntFieldProperty.java +++ b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntFieldProperty.java @@ -37,7 +37,11 @@ public SettableBeanProperty withMutator(BeanPropertyMutator mut) { public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - int v = p.isExpectedNumberIntToken() ? p.getIntValue() : _deserializeInt(p, ctxt); + if (!p.isExpectedNumberIntToken()) { + delegate.deserializeAndSet(p, ctxt, bean); + return; + } + final int v = p.getIntValue(); try { _propertyMutator.intField(bean, _optimizedIndex, v); } catch (Throwable e) { @@ -45,6 +49,16 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, } } + @Override + public Object deserializeSetAndReturn(JsonParser p, + DeserializationContext ctxt, Object instance) throws IOException + { + if (p.isExpectedNumberIntToken()) { + return setAndReturn(instance, p.getIntValue()); + } + return delegate.deserializeSetAndReturn(p, ctxt, instance); + } + @Override public void set(Object bean, Object value) throws IOException { // not optimal (due to boxing), but better than using reflection: @@ -55,12 +69,4 @@ public void set(Object bean, Object value) throws IOException { _reportProblem(bean, v, e); } } - - @Override - public Object deserializeSetAndReturn(JsonParser p, - DeserializationContext ctxt, Object instance) throws IOException - { - int v = p.isExpectedNumberIntToken() ? p.getIntValue() : _deserializeInt(p, ctxt); - return setAndReturn(instance, v); - } } diff --git a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntMethodProperty.java b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntMethodProperty.java index b68532b5..0de38112 100644 --- a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntMethodProperty.java +++ b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableIntMethodProperty.java @@ -37,15 +37,29 @@ public SettableBeanProperty withMutator(BeanPropertyMutator mut) { public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - int v = p.isExpectedNumberIntToken() ? p.getIntValue() : _deserializeInt(p, ctxt); + if (!p.isExpectedNumberIntToken()) { + delegate.deserializeAndSet(p, ctxt, bean); + return; + } + final int v = p.getIntValue(); try { _propertyMutator.intSetter(bean, _optimizedIndex, v); - return; } catch (Throwable e) { _reportProblem(bean, v, e); } } + @Override + public Object deserializeSetAndReturn(JsonParser p, + DeserializationContext ctxt, Object instance) + throws IOException + { + if (p.isExpectedNumberIntToken()) { + return setAndReturn(instance, p.getIntValue()); + } + return delegate.deserializeSetAndReturn(p, ctxt, instance); + } + @Override public void set(Object bean, Object value) throws IOException { // not optimal (due to boxing), but better than using reflection: @@ -56,13 +70,4 @@ public void set(Object bean, Object value) throws IOException { _reportProblem(bean, v, e); } } - - @Override - public Object deserializeSetAndReturn(JsonParser p, - DeserializationContext ctxt, Object instance) - throws IOException - { - int v = p.isExpectedNumberIntToken() ? p.getIntValue() : _deserializeInt(p, ctxt); - return setAndReturn(instance, v); - } } diff --git a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongFieldProperty.java b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongFieldProperty.java index bb18403e..12cd71d9 100644 --- a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongFieldProperty.java +++ b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongFieldProperty.java @@ -37,7 +37,11 @@ public SettableBeanProperty withMutator(BeanPropertyMutator mut) { public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - long v = p.isExpectedNumberIntToken() ? p.getLongValue() : _deserializeLong(p, ctxt); + if (!p.isExpectedNumberIntToken()) { + delegate.deserializeAndSet(p, ctxt, bean); + return; + } + final long v = p.getLongValue(); try { _propertyMutator.longField(bean, _optimizedIndex, v); } catch (Throwable e) { @@ -45,6 +49,16 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, } } + @Override + public Object deserializeSetAndReturn(JsonParser p, + DeserializationContext ctxt, Object instance) throws IOException + { + if (p.isExpectedNumberIntToken()) { + return setAndReturn(instance, p.getLongValue()); + } + return delegate.deserializeSetAndReturn(p, ctxt, instance); + } + @Override public void set(Object bean, Object value) throws IOException { // not optimal (due to boxing), but better than using reflection: @@ -55,12 +69,4 @@ public void set(Object bean, Object value) throws IOException { _reportProblem(bean, v, e); } } - - @Override - public Object deserializeSetAndReturn(JsonParser p, - DeserializationContext ctxt, Object instance) throws IOException - { - long l = p.isExpectedNumberIntToken() ? p.getLongValue() : _deserializeLong(p, ctxt); - return setAndReturn(instance, l); - } } diff --git a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongMethodProperty.java b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongMethodProperty.java index 721fb7b8..3a43746f 100644 --- a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongMethodProperty.java +++ b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableLongMethodProperty.java @@ -37,7 +37,11 @@ public SettableBeanProperty withMutator(BeanPropertyMutator mut) { public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - long v = p.isExpectedNumberIntToken() ? p.getLongValue() : _deserializeLong(p, ctxt); + if (!p.isExpectedNumberIntToken()) { + delegate.deserializeAndSet(p, ctxt, bean); + return; + } + final long v = p.getLongValue(); try { _propertyMutator.longSetter(bean, _optimizedIndex, v); } catch (Throwable e) { @@ -45,6 +49,16 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, } } + @Override + public Object deserializeSetAndReturn(JsonParser p, + DeserializationContext ctxt, Object instance) throws IOException + { + if (p.isExpectedNumberIntToken()) { + return setAndReturn(instance, p.getLongValue()); + } + return delegate.deserializeSetAndReturn(p, ctxt, instance); + } + @Override public void set(Object bean, Object value) throws IOException { // not optimal (due to boxing), but better than using reflection: @@ -55,12 +69,4 @@ public void set(Object bean, Object value) throws IOException { _reportProblem(bean, v, e); } } - - @Override - public Object deserializeSetAndReturn(JsonParser p, - DeserializationContext ctxt, Object instance) throws IOException - { - long l = p.isExpectedNumberIntToken() ? p.getLongValue() : _deserializeLong(p, ctxt); - return setAndReturn(instance, l); - } } diff --git a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringFieldProperty.java b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringFieldProperty.java index 81947d3f..12d3a917 100644 --- a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringFieldProperty.java +++ b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringFieldProperty.java @@ -37,21 +37,11 @@ public SettableBeanProperty withMutator(BeanPropertyMutator mut) { public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - String text; - - if (p.hasToken(JsonToken.VALUE_STRING)) { - text = p.getText(); - } else if (p.hasToken(JsonToken.VALUE_NULL)) { - if (_skipNulls) { - return; - } - text = (String) _nullProvider.getNullValue(ctxt); - } else { - text = p.getValueAsString(); - if (text == null) { - text = _deserializeString(p, ctxt); - } + if (!p.hasToken(JsonToken.VALUE_STRING)) { + delegate.deserializeAndSet(p, ctxt, bean); + return; } + final String text = p.getText(); try { _propertyMutator.stringField(bean, _optimizedIndex, text); } catch (Throwable e) { @@ -63,22 +53,10 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException { - String text; - if (p.hasToken(JsonToken.VALUE_STRING)) { - text = p.getText(); - } else if (p.hasToken(JsonToken.VALUE_NULL)) { - if (_skipNulls) { - return instance; - } - text = (String) _nullProvider.getNullValue(ctxt); - } else { - text = p.getValueAsString(); - if (text == null) { - text = _deserializeString(p, ctxt); - } + return setAndReturn(instance, p.getText()); } - return setAndReturn(instance, text); + return delegate.deserializeSetAndReturn(p, ctxt, instance); } @Override diff --git a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringMethodProperty.java b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringMethodProperty.java index 2e27dbc4..41f29fb0 100644 --- a/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringMethodProperty.java +++ b/afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/SettableStringMethodProperty.java @@ -37,21 +37,11 @@ public SettableBeanProperty withMutator(BeanPropertyMutator mut) { @Override public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - String text; - - if (p.hasToken(JsonToken.VALUE_STRING)) { - text = p.getText(); - } else if (p.hasToken(JsonToken.VALUE_NULL)) { - if (_skipNulls) { - return; - } - text = (String) _nullProvider.getNullValue(ctxt); - } else { - text = p.getValueAsString(); - if (text == null) { - text = _deserializeString(p, ctxt); - } + if (!p.hasToken(JsonToken.VALUE_STRING)) { + delegate.deserializeAndSet(p, ctxt, bean); + return; } + final String text = p.getText(); try { _propertyMutator.stringSetter(bean, _optimizedIndex, text); } catch (Throwable e) { @@ -62,22 +52,10 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object @Override public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException { - String text; - if (p.hasToken(JsonToken.VALUE_STRING)) { - text = p.getText(); - } else if (p.hasToken(JsonToken.VALUE_NULL)) { - if (_skipNulls) { - return instance; - } - text = (String) _nullProvider.getNullValue(ctxt); - } else { - text = p.getValueAsString(); - if (text == null) { - text = _deserializeString(p, ctxt); - } + return setAndReturn(instance, p.getText()); } - return setAndReturn(instance, text); + return delegate.deserializeSetAndReturn(p, ctxt, instance); } @Override diff --git a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestFinalFields.java b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestFinalFields.java index e3fe42c8..c647b9c8 100644 --- a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestFinalFields.java +++ b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/TestFinalFields.java @@ -40,13 +40,14 @@ public Organization(@JsonProperty("id") long id, /********************************************************** */ + private final ObjectMapper MAPPER = newAfterburnerMapper(); + public void testFinalFields() throws Exception { - ObjectMapper mapper = objectMapper(); - String json = mapper.writeValueAsString(new Organization[] { + String json = MAPPER.writeValueAsString(new Organization[] { new Organization(123L, "Corp", new Address(98040, 98021)) }); - Organization[] result = mapper.readValue(json, Organization[].class); + Organization[] result = MAPPER.readValue(json, Organization[].class); assertNotNull(result); assertEquals(1, result.length); assertNotNull(result[0]); @@ -60,11 +61,10 @@ public void testFinalFields42() throws Exception { JsonAddress address = new JsonAddress(-1L, "line1", "line2", "city", "state", "zip", "locale", "timezone"); JsonOrganization organization = new JsonOrganization(-1L, "name", address); - ObjectMapper mapper = objectMapper(); - String json = mapper.writeValueAsString(organization); + String json = MAPPER.writeValueAsString(organization); assertNotNull(json); - JsonOrganization result = mapper.readValue(json, JsonOrganization.class); + JsonOrganization result = MAPPER.readValue(json, JsonOrganization.class); assertNotNull(result); } diff --git a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/convert/TestFailOnPrimitiveFromNullDeserialization.java b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/convert/TestFailOnPrimitiveFromNullDeserialization.java index 448dd36e..fb920e09 100644 --- a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/convert/TestFailOnPrimitiveFromNullDeserialization.java +++ b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/convert/TestFailOnPrimitiveFromNullDeserialization.java @@ -51,19 +51,22 @@ public void testFailPrimitiveFromNull() throws Exception FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, IntBean.class); fail(); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `int` value"); +// verifyException(e, "Cannot coerce `null` to `int` value"); + verifyException(e, "Cannot map `null` into type int"); } try { FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, LongBean.class); fail(); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `long` value"); +// verifyException(e, "Cannot coerce `null` to `long` value"); + verifyException(e, "Cannot map `null` into type long"); } try { FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, BooleanBean.class); fail(); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `boolean` value"); +// verifyException(e, "Cannot coerce `null` to `boolean` value"); + verifyException(e, "Cannot map `null` into type boolean"); } try { FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, DoubleBean.class); diff --git a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/jdk/JDKScalarsDeserTest.java b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/jdk/JDKScalarsDeserTest.java index 3d1983a6..90edc0ad 100644 --- a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/jdk/JDKScalarsDeserTest.java +++ b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/deser/jdk/JDKScalarsDeserTest.java @@ -545,17 +545,17 @@ public void testNullForPrimitivesNotAllowedInts() throws IOException reader.readValue("{\"intValue\":null}"); fail("Expected failure for int + null"); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `int` value"); - // 17-Dec-2020, tatu: A problem, but not sure how/why -// verifyPath(e, "intValue"); + verifyException(e, "Cannot map `null` into type int"); +// verifyException(e, "Cannot coerce `null` to `int` value"); + verifyPath(e, "intValue"); } try { reader.readValue("{\"longValue\":null}"); fail("Expected failure for long + null"); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `long` value"); - // 17-Dec-2020, tatu: A problem, but not sure how/why -// verifyPath(e, "longValue"); + verifyException(e, "Cannot map `null` into type long"); +// verifyException(e, "Cannot coerce `null` to `long` value"); + verifyPath(e, "longValue"); } } @@ -591,9 +591,9 @@ public void testNullForPrimitivesNotAllowedMisc() throws IOException reader.readValue("{\"booleanValue\":null}"); fail("Expected failure for boolean + null"); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `boolean` value"); -// 17-Dec-2020, tatu: path is off not sure why -// verifyPath(e, "booleanValue"); +// verifyException(e, "Cannot coerce `null` to `boolean` value"); + verifyException(e, "Cannot map `null` into type boolean"); + verifyPath(e, "booleanValue"); } try { reader.readValue("{\"charValue\":null}"); diff --git a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/format/MapFormatShapeTest.java b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/format/MapFormatShapeTest.java index 06ced650..4d7885db 100644 --- a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/format/MapFormatShapeTest.java +++ b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/format/MapFormatShapeTest.java @@ -144,7 +144,7 @@ public Set> entrySet() { /********************************************************** */ - final private ObjectMapper MAPPER = objectMapper(); + final private ObjectMapper MAPPER = newAfterburnerMapper(); // for [databind#476]: Maps as POJOs public void testSerializeAsPOJOViaClass() throws Exception diff --git a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/BiggerDataTest.java b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/BiggerDataTest.java index eaca640f..92053b19 100644 --- a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/BiggerDataTest.java +++ b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/roundtrip/BiggerDataTest.java @@ -78,12 +78,12 @@ static class Area { /********************************************************** */ - private final ObjectMapper MAPPER = objectMapper(); - - public void testReading() throws Exception - { - Citm citm0 = MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"), - Citm.class); + private final ObjectMapper MAPPER = newAfterburnerMapper(); + + public void testReading() throws Exception + { + Citm citm0 = MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"), + Citm.class); byte[] cbor = MAPPER.writeValueAsBytes(citm0); diff --git a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/ser/JsonAppendTest.java b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/ser/JsonAppendTest.java index 06b3aa64..cb729881 100644 --- a/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/ser/JsonAppendTest.java +++ b/afterburner/src/test/java/com/fasterxml/jackson/module/afterburner/ser/JsonAppendTest.java @@ -42,8 +42,7 @@ public VirtualBeanPropertyWriter withConfig(MapperConfig config, AnnotatedCla public void testSimpleAppend() throws Exception { - ObjectMapper mapper = objectMapper(); -// ObjectMapper mapper = new ObjectMapper(); + final ObjectMapper mapper = newAfterburnerMapper(); String json = mapper.writeValueAsString(new Pojo("foo")); assertEquals("{\"name\":\"foo\",\"virtual\":\"bar\"}", json); } diff --git a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/OptimizedSettableBeanProperty.java b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/OptimizedSettableBeanProperty.java index c420c7ec..e6b065ef 100644 --- a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/OptimizedSettableBeanProperty.java +++ b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/OptimizedSettableBeanProperty.java @@ -5,14 +5,10 @@ import java.util.logging.Logger; import com.fasterxml.jackson.core.*; -import com.fasterxml.jackson.core.JsonParser.NumberType; -import com.fasterxml.jackson.core.io.NumberInput; + import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.cfg.CoercionAction; -import com.fasterxml.jackson.databind.cfg.CoercionInputShape; import com.fasterxml.jackson.databind.deser.*; import com.fasterxml.jackson.databind.deser.impl.NullsConstantProvider; -import com.fasterxml.jackson.databind.type.LogicalType; import com.fasterxml.jackson.databind.util.ClassUtil; /** @@ -155,311 +151,6 @@ protected void _reportProblem(Object bean, Object value, Throwable e) /********************************************************************** */ - protected final boolean _deserializeBoolean(JsonParser p, DeserializationContext ctxt) throws IOException - { - String text; - switch (p.currentTokenId()) { - case JsonTokenId.ID_STRING: - text = p.getText(); - break; - case JsonTokenId.ID_NUMBER_INT: - // may accept ints too, (0 == false, otherwise true) - - // call returns `null`, Boolean.TRUE or Boolean.FALSE so: - return Boolean.TRUE.equals(_checkIntToBooleanCoercion(p, ctxt, Boolean.TYPE)); - case JsonTokenId.ID_TRUE: // usually caller should have handled but: - return true; - case JsonTokenId.ID_FALSE: - return false; - case JsonTokenId.ID_NULL: // null fine for non-primitive - _verifyNullForPrimitive(ctxt); - return false; - // 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML) - case JsonTokenId.ID_START_OBJECT: - text = ctxt.extractScalarFromObject(p, null, Boolean.TYPE); - break; - case JsonTokenId.ID_START_ARRAY: - // 12-Jun-2020, tatu: For some reason calling `_deserializeFromArray()` won't work so: - if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); - final boolean parsed = _deserializeBoolean(p, ctxt); - _verifyEndArrayForSingle(p, ctxt); - return parsed; - } - // fall through - default: - return ((Boolean) ctxt.handleUnexpectedToken(Boolean.TYPE, p)).booleanValue(); - } - - final CoercionAction act = _checkFromStringCoercion(ctxt, text, - LogicalType.Boolean, Boolean.TYPE); - if (act == CoercionAction.AsNull) { - _verifyNullForPrimitive(ctxt); - return false; - } - if (act == CoercionAction.AsEmpty) { - return false; - } - text = text.trim(); - final int len = text.length(); - - // For [databind#1852] allow some case-insensitive matches (namely, - // true/True/TRUE, false/False/FALSE - if (len == 4) { - if (_isTrue(text)) { - return true; - } - } else if (len == 5) { - if (_isFalse(text)) { - return false; - } - } - if (_hasTextualNull(text)) { - _verifyNullForPrimitiveCoercion(ctxt, text); - return false; - } - Boolean b = (Boolean) ctxt.handleWeirdStringValue(Boolean.TYPE, text, - "only \"true\"/\"True\"/\"TRUE\" or \"false\"/\"False\"/\"FALSE\" recognized"); - return Boolean.TRUE.equals(b); - } - - // 16-Dec-2020, tatu: Copied from "StdDeserializer._parseIntPrimitive()" verbatim: - // - // @since 2.12.1 - protected final int _deserializeInt(JsonParser p, DeserializationContext ctxt) - throws IOException - { - String text; - switch (p.currentTokenId()) { - case JsonTokenId.ID_STRING: - text = p.getText(); - break; - case JsonTokenId.ID_NUMBER_FLOAT: - final CoercionAction act = _checkFloatToIntCoercion(p, ctxt, Integer.TYPE); - if (act == CoercionAction.AsNull) { - return 0; - } - if (act == CoercionAction.AsEmpty) { - return 0; - } - return p.getValueAsInt(); - case JsonTokenId.ID_NUMBER_INT: - return p.getIntValue(); - case JsonTokenId.ID_NULL: - _verifyNullForPrimitive(ctxt); - return 0; - // 16-Dec-2020, tatu: not sure if this will work (no deserializer to pass), - // but we'll do our best - case JsonTokenId.ID_START_OBJECT: - text = ctxt.extractScalarFromObject(p, /* deserializer */ null, Integer.TYPE); - break; - case JsonTokenId.ID_START_ARRAY: - if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); - final int parsed = _deserializeInt(p, ctxt); - _verifyEndArrayForSingle(p, ctxt); - return parsed; - } - // fall through to fail - default: - return ((Number) ctxt.handleUnexpectedToken(getType(), p)).intValue(); - } - - final CoercionAction act = _checkFromStringCoercion(ctxt, text, - LogicalType.Integer, Integer.TYPE); - if (act == CoercionAction.AsNull) { - return 0; // no need to check as does not come from `null`, explicit coercion - } - if (act == CoercionAction.AsEmpty) { - return 0; - } - text = text.trim(); - if (_hasTextualNull(text)) { - _verifyNullForPrimitiveCoercion(ctxt, text); - return 0; - } - return _parseIntPrimitive(ctxt, text); - } - - private final int _parseIntPrimitive(DeserializationContext ctxt, String text) throws IOException - { - try { - if (text.length() > 9) { - long l = Long.parseLong(text); - if (_intOverflow(l)) { - Number v = (Number) ctxt.handleWeirdStringValue(Integer.TYPE, text, - "Overflow: numeric value (%s) out of range of int (%d -%d)", - text, Integer.MIN_VALUE, Integer.MAX_VALUE); - return _nonNullNumber(v).intValue(); - } - return (int) l; - } - return NumberInput.parseInt(text); - } catch (IllegalArgumentException iae) { - Number v = (Number) ctxt.handleWeirdStringValue(Integer.TYPE, text, - "not a valid `int` value"); - return _nonNullNumber(v).intValue(); - } - } - - // 16-Dec-2020, tatu: Copied from "StdDeserializer._parseLongPrimitive()" verbatim: - // - // @since 2.12.1 - protected final long _deserializeLong(JsonParser p, DeserializationContext ctxt) - throws IOException - { - String text; - switch (p.currentTokenId()) { - case JsonTokenId.ID_STRING: - text = p.getText(); - break; - case JsonTokenId.ID_NUMBER_FLOAT: - final CoercionAction act = _checkFloatToIntCoercion(p, ctxt, Long.TYPE); - if (act == CoercionAction.AsNull) { - return 0; - } - if (act == CoercionAction.AsEmpty) { - return 0; - } - return p.getValueAsInt(); - case JsonTokenId.ID_NUMBER_INT: - return p.getIntValue(); - case JsonTokenId.ID_NULL: - _verifyNullForPrimitive(ctxt); - return 0; - // 16-Dec-2020, tatu: not sure if this will work (no deserializer to pass), - // but we'll do our best - case JsonTokenId.ID_START_OBJECT: - text = ctxt.extractScalarFromObject(p, /* deserializer */ null, Long.TYPE); - break; - case JsonTokenId.ID_START_ARRAY: - if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); - final long parsed = _deserializeLong(p, ctxt); - _verifyEndArrayForSingle(p, ctxt); - return parsed; - } - // fall through to fail - default: - return ((Number) ctxt.handleUnexpectedToken(getType(), p)).intValue(); - } - - final CoercionAction act = _checkFromStringCoercion(ctxt, text, - LogicalType.Integer, Long.TYPE); - if (act == CoercionAction.AsNull) { - return 0; // no need to check as does not come from `null`, explicit coercion - } - if (act == CoercionAction.AsEmpty) { - return 0; - } - text = text.trim(); - if (_hasTextualNull(text)) { - _verifyNullForPrimitiveCoercion(ctxt, text); - return 0; - } - return _parseLongPrimitive(ctxt, text); - } - - private final long _parseLongPrimitive(DeserializationContext ctxt, String text) throws IOException - { - try { - return NumberInput.parseLong(text); - } catch (IllegalArgumentException iae) { } - { - Number v = (Number) ctxt.handleWeirdStringValue(Long.TYPE, text, - "not a valid `long` value"); - return _nonNullNumber(v).longValue(); - } - } - - protected final String _deserializeString(JsonParser p, DeserializationContext ctxt) throws IOException - { - switch (p.currentTokenId()) { - case JsonTokenId.ID_STRING: - return p.getText(); - case JsonTokenId.ID_NULL: - return null; - case JsonTokenId.ID_START_ARRAY: - if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); - final String parsed = _deserializeString(p, ctxt); - if (p.nextToken() != JsonToken.END_ARRAY) { - _handleMissingEndArrayForSingle(p, ctxt); - } - return parsed; - } - break; - case JsonTokenId.ID_EMBEDDED_OBJECT: - Object ob = p.getEmbeddedObject(); - if (ob == null) { - return null; - } - if (ob instanceof byte[]) { - return Base64Variants.getDefaultVariant().encode((byte[]) ob, false); - } - // otherwise, try conversion using toString()... - return ob.toString(); - default: - // allow coercions for other scalar types - String text = p.getValueAsString(); - if (text != null) { - return text; - } - } - return (String) ctxt.handleUnexpectedToken(String.class, p); - } - - // // More helper methods from StdDeserializer - - private boolean _hasTextualNull(String value) { - return "null".equals(value); - } - - // [databind#1852] - private boolean _isTrue(String text) { - char c = text.charAt(0); - if (c == 't') { - return "true".equals(text); - } - if (c == 'T') { - return "TRUE".equals(text) || "True".equals(text); - } - return false; - } - - private boolean _isFalse(String text) { - char c = text.charAt(0); - if (c == 'f') { - return "false".equals(text); - } - if (c == 'F') { - return "FALSE".equals(text) || "False".equals(text); - } - return false; - } - - private final boolean _intOverflow(long value) { - return (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE); - } - - private Number _nonNullNumber(Number n) { - if (n == null) { - n = Integer.valueOf(0); - } - return n; - } - - private final static boolean _isBlank(String text) - { - final int len = text.length(); - for (int i = 0; i < len; ++i) { - if (text.charAt(i) > 0x0020) { - return false; - } - } - return true; - } - /** * Helper method used to check whether given deserializer is the default * deserializer implementation: this is necessary to avoid overriding custom @@ -470,136 +161,4 @@ protected boolean _isDefaultDeserializer(JsonDeserializer deser) { || (deser instanceof SuperSonicBeanDeserializer) || ClassUtil.isJacksonStdImpl(deser); } - - private void _verifyEndArrayForSingle(JsonParser p, DeserializationContext ctxt) throws IOException - { - JsonToken t = p.nextToken(); - if (t != JsonToken.END_ARRAY) { - _handleMissingEndArrayForSingle(p, ctxt); - } - } - - private void _handleMissingEndArrayForSingle(JsonParser p, DeserializationContext ctxt) - throws IOException - { - JavaType type = getType(); - ctxt.reportWrongTokenException(type, JsonToken.END_ARRAY, -"Attempted to unwrap single value array for single %s value but there was more than a single value in the array", -getType()); - // 05-May-2016, tatu: Should recover somehow (maybe skip until END_ARRAY); - // but for now just fall through - } - - /* - /********************************************************************** - /* New methods in 2.12.1 to align CoercionConfig handling with databind - /* (copied from "StdDeserializer") - /********************************************************************** - */ - - private CoercionAction _checkFloatToIntCoercion(JsonParser p, DeserializationContext ctxt, - Class rawTargetType) - throws IOException - { - final CoercionAction act = ctxt.findCoercionAction(LogicalType.Integer, - rawTargetType, CoercionInputShape.Float); - if (act == CoercionAction.Fail) { - return _checkCoercionFail(ctxt, act, rawTargetType, p.getNumberValue(), - "Floating-point value ("+p.getText()+")"); - } - return act; - } - - private Boolean _checkIntToBooleanCoercion(JsonParser p, DeserializationContext ctxt, - Class rawTargetType) - throws IOException - { - CoercionAction act = ctxt.findCoercionAction(LogicalType.Boolean, rawTargetType, CoercionInputShape.Integer); - switch (act) { - case Fail: - _checkCoercionFail(ctxt, act, rawTargetType, p.getNumberValue(), - "Integer value ("+p.getText()+")"); - return Boolean.FALSE; - case AsNull: - return null; - case AsEmpty: - return Boolean.FALSE; - default: - } - // 13-Oct-2016, tatu: As per [databind#1324], need to be careful wrt - // degenerate case of huge integers, legal in JSON. - // Also note that number tokens can not have WS to trim: - if (p.getNumberType() == NumberType.INT) { - // but minor optimization for common case is possible: - return p.getIntValue() != 0; - } - return !"0".equals(p.getText()); - } - - private CoercionAction _checkFromStringCoercion(DeserializationContext ctxt, String value, - LogicalType logicalType, Class rawTargetType) - throws IOException - { - final CoercionAction act; - - if (value.isEmpty()) { - act = ctxt.findCoercionAction(logicalType, rawTargetType, - CoercionInputShape.EmptyString); - return _checkCoercionFail(ctxt, act, rawTargetType, value, - "empty String (\"\")"); - } else if (_isBlank(value)) { - act = ctxt.findCoercionFromBlankString(logicalType, rawTargetType, CoercionAction.Fail); - return _checkCoercionFail(ctxt, act, rawTargetType, value, - "blank String (all whitespace)"); - } else { - act = ctxt.findCoercionAction(logicalType, rawTargetType, CoercionInputShape.String); - if (act == CoercionAction.Fail) { - // since it MIGHT (but might not), create desc here, do not use helper - ctxt.reportInputMismatch(this, -"Cannot coerce String value (\"%s\") to %s (but might if coercion using `CoercionConfig` was enabled)", -value, _coercedTypeDesc()); - } - } - return act; - } - - private CoercionAction _checkCoercionFail(DeserializationContext ctxt, - CoercionAction act, Class targetType, Object inputValue, - String inputDesc) - throws IOException - { - if (act == CoercionAction.Fail) { - // 16-Dec-2020, tatu: Let's hope `null` for deserializer is ok... - ctxt.reportBadCoercion(null, targetType, inputValue, -"Cannot coerce %s to %s (but could if coercion was enabled using `CoercionConfig`)", -inputDesc, _coercedTypeDesc()); - } - return act; - } - - private void _verifyNullForPrimitive(DeserializationContext ctxt) - throws JsonMappingException - { - if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) { - ctxt.reportInputMismatch(this, -"Cannot coerce `null` to %s (disable `DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES` to allow)", - _coercedTypeDesc()); - } - } - - private final void _verifyNullForPrimitiveCoercion(DeserializationContext ctxt, - String str) throws JsonMappingException - { - if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) { - String strDesc = str.isEmpty() ? "empty String (\"\")" : String.format("String \"%s\"", str); - ctxt.reportInputMismatch(this, -"Cannot coerce %s to %s (disable `DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES` to allow)", - strDesc, _coercedTypeDesc()); - } - } - - // Simplified as we only ever get simple scalar types - private String _coercedTypeDesc() { - return ClassUtil.getTypeDescription(getType()) +" value"; - } } diff --git a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableBooleanProperty.java b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableBooleanProperty.java index 10f6bb37..a48c45f1 100644 --- a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableBooleanProperty.java +++ b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableBooleanProperty.java @@ -38,7 +38,8 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object } else if (t == JsonToken.VALUE_FALSE) { b = false; } else { - b = _deserializeBoolean(p, ctxt); + delegate.deserializeAndSet(p, ctxt, bean); + return; } try { _optimizedSetter.accept(bean, b); @@ -47,6 +48,20 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object } } + @Override + public Object deserializeSetAndReturn(JsonParser p, + DeserializationContext ctxt, Object instance) throws IOException + { + JsonToken t = p.currentToken(); + if (t == JsonToken.VALUE_TRUE) { + return setAndReturn(instance, Boolean.TRUE); + } + if (t == JsonToken.VALUE_FALSE) { + return setAndReturn(instance, Boolean.FALSE); + } + return delegate.deserializeSetAndReturn(p, ctxt, instance); + } + @Override public void set(Object bean, Object value) throws IOException { // not optimal (due to boxing), but better than using reflection: @@ -57,20 +72,4 @@ public void set(Object bean, Object value) throws IOException { _reportProblem(bean, b, e); } } - - @Override - public Object deserializeSetAndReturn(JsonParser p, - DeserializationContext ctxt, Object instance) throws IOException - { - boolean b; - JsonToken t = p.currentToken(); - if (t == JsonToken.VALUE_TRUE) { - b = true; - } else if (t == JsonToken.VALUE_FALSE) { - b = false; - } else { - b = _deserializeBoolean(p, ctxt); - } - return setAndReturn(instance, b); - } } diff --git a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableIntProperty.java b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableIntProperty.java index cbb4b23b..93fb3828 100644 --- a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableIntProperty.java +++ b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableIntProperty.java @@ -34,7 +34,11 @@ protected SettableBeanProperty withDelegate(SettableBeanProperty del) { public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - int v = p.isExpectedNumberIntToken() ? p.getIntValue() : _deserializeInt(p, ctxt); + if (!p.isExpectedNumberIntToken()) { + delegate.deserializeAndSet(p, ctxt, bean); + return; + } + final int v = p.getIntValue(); try { _optimizedSetter.accept(bean, v); } catch (Throwable e) { @@ -42,6 +46,17 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, } } + @Override + public Object deserializeSetAndReturn(JsonParser p, + DeserializationContext ctxt, Object instance) + throws IOException + { + if (p.isExpectedNumberIntToken()) { + return setAndReturn(instance, p.getIntValue()); + } + return delegate.deserializeSetAndReturn(p, ctxt, instance); + } + @Override public void set(Object bean, Object value) throws IOException { // not optimal (due to boxing), but better than using reflection: @@ -52,13 +67,4 @@ public void set(Object bean, Object value) throws IOException { _reportProblem(bean, v, e); } } - - @Override - public Object deserializeSetAndReturn(JsonParser p, - DeserializationContext ctxt, Object instance) - throws IOException - { - int v = p.isExpectedNumberIntToken() ? p.getIntValue() : _deserializeInt(p, ctxt); - return setAndReturn(instance, v); - } } diff --git a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableLongProperty.java b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableLongProperty.java index 8491a1e3..8f3238fa 100644 --- a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableLongProperty.java +++ b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableLongProperty.java @@ -34,7 +34,11 @@ protected SettableBeanProperty withDelegate(SettableBeanProperty del) { public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - long v = p.isExpectedNumberIntToken() ? p.getLongValue() : _deserializeLong(p, ctxt); + if (!p.isExpectedNumberIntToken()) { + delegate.deserializeAndSet(p, ctxt, bean); + return; + } + final long v = p.getLongValue(); try { _optimizedSetter.accept(bean, v); } catch (Throwable e) { @@ -42,6 +46,16 @@ public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, } } + @Override + public Object deserializeSetAndReturn(JsonParser p, + DeserializationContext ctxt, Object instance) throws IOException + { + if (p.isExpectedNumberIntToken()) { + return setAndReturn(instance, p.getLongValue()); + } + return delegate.deserializeSetAndReturn(p, ctxt, instance); + } + @Override public void set(Object bean, Object value) throws IOException { // not optimal (due to boxing), but better than using reflection: @@ -52,12 +66,4 @@ public void set(Object bean, Object value) throws IOException { _reportProblem(bean, v, e); } } - - @Override - public Object deserializeSetAndReturn(JsonParser p, - DeserializationContext ctxt, Object instance) throws IOException - { - long l = p.isExpectedNumberIntToken() ? p.getLongValue() : _deserializeLong(p, ctxt); - return setAndReturn(instance, l); - } } diff --git a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableStringProperty.java b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableStringProperty.java index a8850283..20089308 100644 --- a/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableStringProperty.java +++ b/blackbird/src/main/java/com/fasterxml/jackson/module/blackbird/deser/SettableStringProperty.java @@ -34,43 +34,20 @@ protected SettableBeanProperty withDelegate(SettableBeanProperty del) { @Override public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - String text; - - if (p.hasToken(JsonToken.VALUE_STRING)) { - text = p.getText(); - } else if (p.hasToken(JsonToken.VALUE_NULL)) { - if (_skipNulls) { - return; - } - text = (String) _nullProvider.getNullValue(ctxt); - } else { - text = p.getValueAsString(); - if (text == null) { - text = _deserializeString(p, ctxt); - } + if (!p.hasToken(JsonToken.VALUE_STRING)) { + delegate.deserializeAndSet(p, ctxt, bean); + return; } - set(bean, text); + set(bean, p.getText()); } @Override public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException { - String text; - if (p.hasToken(JsonToken.VALUE_STRING)) { - text = p.getText(); - } else if (p.hasToken(JsonToken.VALUE_NULL)) { - if (_skipNulls) { - return instance; - } - text = (String) _nullProvider.getNullValue(ctxt); - } else { - text = p.getValueAsString(); - if (text == null) { - text = _deserializeString(p, ctxt); - } + return setAndReturn(instance, p.getText()); } - return setAndReturn(instance, text); + return delegate.deserializeSetAndReturn(p, ctxt, instance); } @Override diff --git a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/TestFinalFields.java b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/TestFinalFields.java index 37169fbd..520a826e 100644 --- a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/TestFinalFields.java +++ b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/TestFinalFields.java @@ -40,13 +40,14 @@ public Organization(@JsonProperty("id") long id, /********************************************************** */ + private final ObjectMapper MAPPER = newBlackbirdMapper(); + public void testFinalFields() throws Exception { - ObjectMapper mapper = objectMapper(); - String json = mapper.writeValueAsString(new Organization[] { + String json = MAPPER.writeValueAsString(new Organization[] { new Organization(123L, "Corp", new Address(98040, 98021)) }); - Organization[] result = mapper.readValue(json, Organization[].class); + Organization[] result = MAPPER.readValue(json, Organization[].class); assertNotNull(result); assertEquals(1, result.length); assertNotNull(result[0]); @@ -60,11 +61,10 @@ public void testFinalFields42() throws Exception { JsonAddress address = new JsonAddress(-1L, "line1", "line2", "city", "state", "zip", "locale", "timezone"); JsonOrganization organization = new JsonOrganization(-1L, "name", address); - ObjectMapper mapper = objectMapper(); - String json = mapper.writeValueAsString(organization); + String json = MAPPER.writeValueAsString(organization); assertNotNull(json); - JsonOrganization result = mapper.readValue(json, JsonOrganization.class); + JsonOrganization result = MAPPER.readValue(json, JsonOrganization.class); assertNotNull(result); } diff --git a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/convert/TestFailOnPrimitiveFromNullDeserialization.java b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/convert/TestFailOnPrimitiveFromNullDeserialization.java index 454464d8..2aa6e768 100644 --- a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/convert/TestFailOnPrimitiveFromNullDeserialization.java +++ b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/convert/TestFailOnPrimitiveFromNullDeserialization.java @@ -60,19 +60,19 @@ public void testFailPrimitiveFromNull() throws Exception FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, IntBean.class); fail(); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `int` value"); + verifyException(e, "Cannot map `null` into type int"); } try { FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, LongBean.class); fail(); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `long` value"); + verifyException(e, "Cannot map `null` into type long"); } try { FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, BooleanBean.class); fail(); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `boolean` value"); + verifyException(e, "Cannot map `null` into type boolean"); } try { FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, DoubleBean.class); diff --git a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/filter/IgnoreCreatorProp1317Test.java b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/filter/IgnoreCreatorProp1317Test.java index ad0a6a54..d66679ba 100644 --- a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/filter/IgnoreCreatorProp1317Test.java +++ b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/filter/IgnoreCreatorProp1317Test.java @@ -42,7 +42,7 @@ public void setNotIgnore(String notIgnore) { } public void testThatJsonIgnoreWorksWithConstructorProperties() throws Exception { - ObjectMapper om = objectMapper(); + final ObjectMapper om = newBlackbirdMapper(); Testing testing = new Testing("shouldBeIgnored", "notIgnore"); String json = om.writeValueAsString(testing); // System.out.println(json); diff --git a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/jdk/JDKScalarsTest.java b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/jdk/JDKScalarsTest.java index c1d412aa..756a6b73 100644 --- a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/jdk/JDKScalarsTest.java +++ b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/deser/jdk/JDKScalarsTest.java @@ -557,10 +557,8 @@ public void testNullForPrimitivesNotAllowedInts() throws IOException reader.readValue("{\"longValue\":null}"); fail("Expected failure for long + null"); } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce `null` to `long` value"); - - // 17-Dec-2020, tatu: A problem, but not sure how/why -// verifyPath(e, "longValue"); + verifyException(e, "Cannot map `null` into type long"); + verifyPath(e, "longValue"); } } diff --git a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/format/MapFormatShapeTest.java b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/format/MapFormatShapeTest.java index 880cebcc..67def7c0 100644 --- a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/format/MapFormatShapeTest.java +++ b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/format/MapFormatShapeTest.java @@ -144,7 +144,7 @@ public Set> entrySet() { /********************************************************** */ - final private ObjectMapper MAPPER = objectMapper(); + final private ObjectMapper MAPPER = newBlackbirdMapper(); // for [databind#476]: Maps as POJOs public void testSerializeAsPOJOViaClass() throws Exception diff --git a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/roundtrip/BiggerDataTest.java b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/roundtrip/BiggerDataTest.java index f91f0271..4023557c 100644 --- a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/roundtrip/BiggerDataTest.java +++ b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/roundtrip/BiggerDataTest.java @@ -78,12 +78,12 @@ static class Area { /********************************************************** */ - private final ObjectMapper MAPPER = objectMapper(); - - public void testReading() throws Exception - { - Citm citm0 = MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"), - Citm.class); + private final ObjectMapper MAPPER = newBlackbirdMapper(); + + public void testReading() throws Exception + { + Citm citm0 = MAPPER.readValue(getClass().getResourceAsStream("/data/citm_catalog.json"), + Citm.class); byte[] cbor = MAPPER.writeValueAsBytes(citm0); diff --git a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/ser/JsonAppendTest.java b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/ser/JsonAppendTest.java index e23d51c2..6dc8d345 100644 --- a/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/ser/JsonAppendTest.java +++ b/blackbird/src/test/java/com/fasterxml/jackson/module/blackbird/ser/JsonAppendTest.java @@ -42,8 +42,7 @@ public VirtualBeanPropertyWriter withConfig(MapperConfig config, AnnotatedCla public void testSimpleAppend() throws Exception { - ObjectMapper mapper = objectMapper(); -// ObjectMapper mapper = new ObjectMapper(); + ObjectMapper mapper = newBlackbirdMapper(); String json = mapper.writeValueAsString(new Pojo("foo")); assertEquals("{\"name\":\"foo\",\"virtual\":\"bar\"}", json); } diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 893f75f7..41113a22 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -72,3 +72,8 @@ Steven Schlansker (stevenschlansker@github) * Contributed #85: Add Blackbird module -- alternative for Afterburner that works better with new(er) JVMs (2.12.0) + +Carter Kozak (carterkozak@github) + +* Reported #120: Afterburner does not support the new CoercionConfig + (2.12.1) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index a04d9c76..76ddc764 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -12,6 +12,11 @@ Modules: === Releases === ------------------------------------------------------------------------ +2.12.1 (not yet released) + +#120: Afterburner does not support the new CoercionConfig + (reported by Carter K) + 2.12.0 (29-Nov-2020) #85: Add Blackbird module -- alternative for Afterburner that works better with