com.fasterxml.jackson.core.StreamWriteConstraints Maven / Gradle / Ivy
package com.fasterxml.jackson.core;
import com.fasterxml.jackson.core.exc.StreamConstraintsException;
/**
* The constraints to use for streaming writes: used to guard against problematic
* output by preventing processing of "too big" output constructs (values,
* structures).
* Constraints are registered with {@code TokenStreamFactory} (such as
* {@code JsonFactory}); if nothing explicitly specified, default
* constraints are used.
*
* Currently constrained aspects, with default settings, are:
*
* - Maximum Nesting depth: default 1000 (see {@link #DEFAULT_MAX_DEPTH})
*
*
*
* @since 2.16
*/
public class StreamWriteConstraints
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* Default setting for maximum depth: see {@link Builder#maxNestingDepth(int)} for details.
*/
public static final int DEFAULT_MAX_DEPTH = 1000;
protected final int _maxNestingDepth;
private static StreamWriteConstraints DEFAULT = new StreamWriteConstraints(DEFAULT_MAX_DEPTH);
/**
* Override the default StreamWriteConstraints. These defaults are only used when {@link JsonFactory}
* instances are not configured with their own StreamWriteConstraints.
*
* Library maintainers should not set this as it will affect other code that uses Jackson.
* Library maintainers who want to configure StreamWriteConstraints for the Jackson usage within their
* lib should create ObjectMapper
instances that have a {@link JsonFactory} instance with
* the required StreamWriteConstraints.
*
* This method is meant for users delivering applications. If they use this, they set it when they start
* their application to avoid having other code initialize their mappers before the defaults are overridden.
*
* @param streamWriteConstraints new default for StreamWriteConstraints (a null value will reset to built-in default)
* @see #defaults()
* @see #builder()
*/
public static void overrideDefaultStreamWriteConstraints(final StreamWriteConstraints streamWriteConstraints) {
if (streamWriteConstraints == null) {
DEFAULT = new StreamWriteConstraints(DEFAULT_MAX_DEPTH);
} else {
DEFAULT = streamWriteConstraints;
}
}
public static final class Builder {
private int maxNestingDepth;
/**
* Sets the maximum nesting depth. The depth is a count of objects and arrays that have not
* been closed, `{` and `[` respectively.
*
* @param maxNestingDepth the maximum depth
*
* @return this builder
* @throws IllegalArgumentException if the maxNestingDepth is set to a negative value
*/
public Builder maxNestingDepth(final int maxNestingDepth) {
if (maxNestingDepth < 0) {
throw new IllegalArgumentException("Cannot set maxNestingDepth to a negative value");
}
this.maxNestingDepth = maxNestingDepth;
return this;
}
Builder() {
this(DEFAULT_MAX_DEPTH);
}
Builder(final int maxNestingDepth) {
this.maxNestingDepth = maxNestingDepth;
}
Builder(StreamWriteConstraints src) {
maxNestingDepth = src._maxNestingDepth;
}
public StreamWriteConstraints build() {
return new StreamWriteConstraints(maxNestingDepth);
}
}
/*
/**********************************************************************
/* Life-cycle
/**********************************************************************
*/
protected StreamWriteConstraints(final int maxNestingDepth) {
_maxNestingDepth = maxNestingDepth;
}
public static Builder builder() {
return new Builder();
}
/**
* @return the default {@link StreamWriteConstraints} (when none is set on the {@link JsonFactory} explicitly)
* @see #overrideDefaultStreamWriteConstraints(StreamWriteConstraints)
*/
public static StreamWriteConstraints defaults() {
return DEFAULT;
}
/**
* @return New {@link Builder} initialized with settings of this constraints
* instance
*/
public Builder rebuild() {
return new Builder(this);
}
/*
/**********************************************************************
/* Accessors
/**********************************************************************
*/
/**
* Accessor for maximum depth.
* see {@link Builder#maxNestingDepth(int)} for details.
*
* @return Maximum allowed depth
*/
public int getMaxNestingDepth() {
return _maxNestingDepth;
}
/*
/**********************************************************************
/* Convenience methods for validation, document limits
/**********************************************************************
*/
/**
* Convenience method that can be used to verify that the
* nesting depth does not exceed the maximum specified by this
* constraints object: if it does, a
* {@link StreamConstraintsException}
* is thrown.
*
* @param depth count of unclosed objects and arrays
*
* @throws StreamConstraintsException If depth exceeds maximum
*/
public void validateNestingDepth(int depth) throws StreamConstraintsException
{
if (depth > _maxNestingDepth) {
throw _constructException(
"Document nesting depth (%d) exceeds the maximum allowed (%d, from %s)",
depth, _maxNestingDepth,
_constrainRef("getMaxNestingDepth"));
}
}
/*
/**********************************************************************
/* Error reporting
/**********************************************************************
*/
// @since 2.16
protected StreamConstraintsException _constructException(String msgTemplate, Object... args) throws StreamConstraintsException {
throw new StreamConstraintsException(String.format(msgTemplate, args));
}
// @since 2.16
protected String _constrainRef(String method) {
return "`StreamWriteConstraints."+method+"()`";
}
}