diff --git a/release-notes/CREDITS b/release-notes/CREDITS
index 55a7b01f2f..301f06b74b 100644
--- a/release-notes/CREDITS
+++ b/release-notes/CREDITS
@@ -271,3 +271,9 @@ Michal Letynski (mletynski@github)
* Suggested #296: Serialization of transient fields with public getters (add
MapperFeature.PROPAGATE_TRANSIENT_MARKER)
(2.6.0)
+
+Jeff Schnitzer (stickfigure@github)
+ * Suggested #504: Add `DeserializationFeature.USE_LONG_FOR_INTS`
+ (2.6.0)
+
+
diff --git a/release-notes/VERSION b/release-notes/VERSION
index fdb0c5c289..157887b6ed 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -14,6 +14,8 @@ Project: jackson-databind
#312: Support Type Id mappings where two ids map to same Class
#348: ObjectMapper.valueToTree does not work with @JsonRawValue
(reported by Chris P, pimlottc@github)
+#504: Add `DeserializationFeature.USE_LONG_FOR_INTS`
+ (suggested by Jeff S)
#649: Make `BeanDeserializer` use new `parser.nextFieldName()` and `.hasTokenId()` methods
#664: Add `DeserializationFeature.ACCEPT_FLOAT_AS_INT` to prevent coercion of floating point
numbers int `int`/`long`/`Integer`/`Long`
@@ -51,6 +53,7 @@ Project: jackson-databind
timezone id for date/time values (as opposed to timezone offset)
#795: Converter annotation not honored for abstract types
(reported by myrosia@github)
+#797: `JsonNodeFactory` method `numberNode(long)` produces `IntNode` for small numbers
- Remove old cglib compatibility tests; cause problems in Eclipse
2.5.4 (not yet released)
diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java
index cbee948b31..653d29bb41 100644
--- a/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java
+++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java
@@ -648,7 +648,7 @@ public final boolean isEnabled(JsonParser.Feature f, JsonFactory factory) {
}
/**
- * "Bulk" access method for checking that all features specified by
+ * Bulk access method for checking that all features specified by
* mask are enabled.
*
* @since 2.3
@@ -657,6 +657,20 @@ public final boolean hasDeserializationFeatures(int featureMask) {
return (_deserFeatures & featureMask) == featureMask;
}
+ /**
+ * Bulk access method for checking that at least one of features specified by
+ * mask is enabled.
+ *
+ * @since 2.6
+ */
+ public final boolean hasSomeOfFeatures(int featureMask) {
+ return (_deserFeatures & featureMask) != 0;
+ }
+
+ /**
+ * Bulk access method for getting the bit mask of all {@link DeserializationFeature}s
+ * that are enabled.
+ */
public final int getDeserializationFeatures() {
return _deserFeatures;
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
index 35ca839769..6ad9b758d2 100644
--- a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
+++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
@@ -291,13 +291,33 @@ public final boolean isEnabled(DeserializationFeature feat) {
}
/**
- * "Bulk" access method for checking that all features specified by
+ * Bulk access method for getting the bit mask of all {@link DeserializationFeature}s
+ * that are enabled.
+ *
+ * @since 2.6
+ */
+ public final int getDeserializationFeatures() {
+ return _featureFlags;
+ }
+
+ /**
+ * Bulk access method for checking that all features specified by
* mask are enabled.
*
* @since 2.3
*/
public final boolean hasDeserializationFeatures(int featureMask) {
- return _config.hasDeserializationFeatures(featureMask);
+ return (_featureFlags & featureMask) == featureMask;
+ }
+
+ /**
+ * Bulk access method for checking that at least one of features specified by
+ * mask is enabled.
+ *
+ * @since 2.6
+ */
+ public final boolean hasSomeOfFeatures(int featureMask) {
+ return (_featureFlags & featureMask) != 0;
}
/**
diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java
index e36574aabd..c0f2602c32 100644
--- a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java
+++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java
@@ -53,13 +53,35 @@ public enum DeserializationFeature implements ConfigFeature
* which is either {@link Integer}, {@link Long} or
* {@link java.math.BigInteger}, depending on number of digits.
*
- * Feature is disabled by default, meaning that "untyped" floating
- * point numbers will by default be deserialized using whatever
+ * Feature is disabled by default, meaning that "untyped" integral
+ * numbers will by default be deserialized using whatever
* is the most compact integral type, to optimize efficiency.
*/
USE_BIG_INTEGER_FOR_INTS(false),
- // [JACKSON-652]
+ /**
+ * Feature that determines how "small" JSON integral (non-floating-point)
+ * numbers -- ones that fit in 32-bit signed integer (`int`) -- are bound
+ * when target type is loosely typed as {@link Object} or {@link Number}
+ * (or within untyped {@link java.util.Map} or {@link java.util.Collection} context).
+ * If enabled, such values will be deserialized as {@link java.lang.Long};
+ * if disabled, they will be deserialized as "smallest" available type,
+ * {@link Integer}.
+ * In addition, if enabled, trying to bind values that do not fit in {@link java.lang.Long}
+ * will throw a {@link com.fasterxml.jackson.core.JsonProcessingException}.
+ *
+ * Note: if {@link #USE_BIG_INTEGER_FOR_INTS} is enabled, it has precedence
+ * over this setting, forcing use of {@link java.math.BigInteger} for all
+ * integral values.
+ *
+ * Feature is disabled by default, meaning that "untyped" integral
+ * numbers will by default be deserialized using {@link java.lang.Integer}
+ * if value fits.
+ *
+ * @since 2.6
+ */
+ USE_LONG_FOR_INTS(false),
+
/**
* Feature that determines whether JSON Array is mapped to
* Object[] or List<Object> when binding
@@ -402,4 +424,4 @@ private DeserializationFeature(boolean defaultState) {
* @since 2.5
*/
public boolean enabledIn(int flags) { return (flags & _mask) != 0; }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
index 5846a2e26c..3033a09d75 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
@@ -1271,7 +1271,7 @@ public ObjectMapper setSerializationInclusion(JsonInclude.Include incl) {
* Method for specifying {@link PrettyPrinter} to use when "default pretty-printing"
* is enabled (by enabling {@link SerializationFeature#INDENT_OUTPUT})
*
- * @param pp
+ * @param pp Pretty printer to use by default.
*
* @return This mapper, useful for call-chaining
*
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java
index 2046f2d4da..0678620821 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java
@@ -331,15 +331,26 @@ protected final JsonNode deserializeAny(JsonParser p, DeserializationContext ctx
protected final JsonNode _fromInt(JsonParser p, DeserializationContext ctxt,
JsonNodeFactory nodeFactory) throws IOException
{
- JsonParser.NumberType nt = p.getNumberType();
- if (nt == JsonParser.NumberType.BIG_INTEGER
- || ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
- return nodeFactory.numberNode(p.getBigIntegerValue());
+ JsonParser.NumberType nt;
+ int feats = ctxt.getDeserializationFeatures();
+ if ((feats & F_MASK_INT_COERCIONS) != 0) {
+ if (DeserializationFeature.USE_BIG_INTEGER_FOR_INTS.enabledIn(feats)) {
+ nt = JsonParser.NumberType.BIG_INTEGER;
+ } else if (DeserializationFeature.USE_LONG_FOR_INTS.enabledIn(feats)) {
+ nt = JsonParser.NumberType.LONG;
+ } else {
+ nt = p.getNumberType();
+ }
+ } else {
+ nt = p.getNumberType();
}
if (nt == JsonParser.NumberType.INT) {
return nodeFactory.numberNode(p.getIntValue());
}
- return nodeFactory.numberNode(p.getLongValue());
+ if (nt == JsonParser.NumberType.LONG) {
+ return nodeFactory.numberNode(p.getLongValue());
+ }
+ return nodeFactory.numberNode(p.getBigIntegerValue());
}
protected final JsonNode _fromFloat(JsonParser p, DeserializationContext ctxt,
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/NumberDeserializers.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/NumberDeserializers.java
index 50f3c366ea..0a1df4ca61 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/NumberDeserializers.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/NumberDeserializers.java
@@ -410,21 +410,24 @@ public Double deserializeWithType(JsonParser jp, DeserializationContext ctxt,
@SuppressWarnings("serial")
@JacksonStdImpl
public static class NumberDeserializer
- extends StdScalarDeserializer
+ extends StdScalarDeserializer