Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrofit ContentReference with ErrorReportConfiguration #1069

Closed
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ public abstract class ParserMinimalBase extends JsonParser
* as part of error messages.
*
* @since 2.9
* @deprecated Since 2.16
* @see ErrorReportConfiguration#getMaxErrorTokenLength()
*/
@Deprecated
protected final static int MAX_ERROR_TOKEN_LENGTH = 256;

/*
Expand Down
55 changes: 52 additions & 3 deletions src/main/java/com/fasterxml/jackson/core/io/ContentReference.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.fasterxml.jackson.core.io;

import com.fasterxml.jackson.core.ErrorReportConfiguration;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
Expand Down Expand Up @@ -52,6 +54,8 @@ public class ContentReference
* logs.
*
* @since 2.9
* @deprecated Since 2.16. Use {@link ErrorReportConfiguration#DEFAULT_MAX_RAW_CONTENT_LENGTH} or
* {@link ErrorReportConfiguration.Builder#maxRawContentLength(int)} instead.
*/
public static final int DEFAULT_MAX_CONTENT_SNIPPET = 500;

Expand Down Expand Up @@ -81,6 +85,13 @@ public class ContentReference
*/
protected final boolean _isContentTextual;

/**
* max raw content to return as configured
*
* @since 2.16
*/
protected final int _maxRawContentLength;

/*
/**********************************************************************
/* Life-cycle
Expand All @@ -91,13 +102,34 @@ protected ContentReference(boolean isContentTextual, Object rawContent) {
this(isContentTextual, rawContent, -1, -1);
}

/**
* @deprecated Since 2.16. Use {@link #ContentReference(boolean, Object, int, int, ErrorReportConfiguration)} instead.
*/
protected ContentReference(boolean isContentTextual, Object rawContent,
int offset, int length)
{
this(isContentTextual, rawContent, offset, length, ErrorReportConfiguration.defaults());
}

/**
* @since
*/
protected ContentReference(boolean isContentTextual, Object rawContent,
int offset, int length, ErrorReportConfiguration errorReportConfiguration)
{
_isContentTextual = isContentTextual;
_rawContent = rawContent;
_offset = offset;
_length = length;
_maxRawContentLength = errorReportConfiguration.getMaxRawContentLength();
}

/**
* @since 2.16
*/
public ContentReference(boolean isContentTextual, Object rawContent,
ErrorReportConfiguration errorReportConfiguration) {
this(isContentTextual, rawContent, -1, -1, errorReportConfiguration);
}

/**
Expand Down Expand Up @@ -130,8 +162,24 @@ public static ContentReference construct(boolean isContentTextual, Object rawCon
}

public static ContentReference construct(boolean isContentTextual, Object rawContent,
int offset, int length) {
return new ContentReference(isContentTextual, rawContent, offset, length);
int offset, int length) {
return new ContentReference(isContentTextual, rawContent, offset, length, ErrorReportConfiguration.defaults());
}

/**
* @since 2.16
*/
public static ContentReference construct(boolean isContentTextual, Object rawContent,
int offset, int length, ErrorReportConfiguration errorReportConfiguration)
{
return new ContentReference(isContentTextual, rawContent, offset, length, errorReportConfiguration);
}

/**
* @since 2.16
*/
public static ContentReference construct(boolean isContentTextual, Object rawContent, ErrorReportConfiguration errorReportConfiguration) {
return new ContentReference(isContentTextual, rawContent, errorReportConfiguration);
}

/**
Expand Down Expand Up @@ -203,10 +251,11 @@ public Object getRawContent() {
* which content is counted, either bytes or chars) to use for truncation
* (so as not to include full content for humongous sources or targets)
*
* @see ErrorReportConfiguration#getMaxErrorTokenLength()
* @return Maximum content snippet to include before truncating
*/
protected int maxContentSnippetLength() {
return DEFAULT_MAX_CONTENT_SNIPPET;
return _maxRawContentLength;
}

/*
Expand Down
55 changes: 43 additions & 12 deletions src/main/java/com/fasterxml/jackson/core/io/IOContext.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.fasterxml.jackson.core.io;

import com.fasterxml.jackson.core.ErrorReportConfiguration;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.StreamReadConstraints;
import com.fasterxml.jackson.core.StreamWriteConstraints;
Expand Down Expand Up @@ -68,6 +69,12 @@ public class IOContext
*/
protected final StreamReadConstraints _streamReadConstraints;

/**
* @see ErrorReportConfiguration
* @since 2.16
*/
protected final ErrorReportConfiguration _errorReportConfiguration;

/**
* @since 2.16
*/
Expand Down Expand Up @@ -129,18 +136,37 @@ public class IOContext
* @param managedResource Whether input source is managed (owned) by Jackson library
*
* @since 2.16
* @deprecated Since 2.16, use {@link #IOContext(StreamReadConstraints, StreamWriteConstraints, BufferRecycler,
* ContentReference, boolean, ErrorReportConfiguration)} instead.
*/
@Deprecated
public IOContext(StreamReadConstraints src, StreamWriteConstraints swc, BufferRecycler br,
ContentReference contentRef, boolean managedResource)
{
_streamReadConstraints = (src == null) ?
StreamReadConstraints.defaults() : src;
_streamWriteConstraints = (swc == null) ?
StreamWriteConstraints.defaults() : swc;
this(src, swc, br, contentRef, managedResource, ErrorReportConfiguration.defaults());
}

/**
* Main constructor to use.
*
* @param src constraints for streaming reads
* @param swc constraints for streaming writes
* @param br BufferRecycler to use, if any ({@code null} if none)
* @param contentRef Input source reference for location reporting
* @param managedResource Whether input source is managed (owned) by Jackson library
*
* @since 2.16
*/
public IOContext(StreamReadConstraints src, StreamWriteConstraints swc, BufferRecycler br,
ContentReference contentRef, boolean managedResource, ErrorReportConfiguration erc)
{
_streamReadConstraints = src;
_streamWriteConstraints = swc;
_bufferRecycler = br;
_contentReference = contentRef;
_sourceRef = contentRef.getRawContent();
_managedResource = managedResource;
_errorReportConfiguration = erc;
}

/**
Expand All @@ -150,19 +176,14 @@ public IOContext(StreamReadConstraints src, StreamWriteConstraints swc, BufferRe
* @param managedResource Whether input source is managed (owned) by Jackson library
*
* @since 2.15
* @deprecated use v2.16 constructor with additional <code>StreamWriteConstraints</code>
* @deprecated Since 2.16. Use {@link #IOContext(StreamReadConstraints, StreamWriteConstraints, BufferRecycler,
* ContentReference, boolean, ErrorReportConfiguration)} instead.
*/
@Deprecated
public IOContext(StreamReadConstraints src, BufferRecycler br,
ContentReference contentRef, boolean managedResource)
{
_streamReadConstraints = (src == null) ?
StreamReadConstraints.defaults() : src;
_streamWriteConstraints = StreamWriteConstraints.defaults();
_bufferRecycler = br;
_contentReference = contentRef;
_sourceRef = contentRef.getRawContent();
_managedResource = managedResource;
this(src, StreamWriteConstraints.defaults(), br, contentRef, managedResource, ErrorReportConfiguration.defaults());
}

/**
Expand Down Expand Up @@ -199,6 +220,16 @@ public StreamWriteConstraints streamWriteConstraints() {
return _streamWriteConstraints;
}

/**
* Returns : {@link ErrorReportConfiguration}, container for configuration values used when
* handling errorneous token inputs.
*
* @since 2.16
*/
public ErrorReportConfiguration errorReportConfiguration() {
return _errorReportConfiguration;
}

public void setEncoding(JsonEncoding enc) {
_encoding = enc;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3033,7 +3033,7 @@ protected void _reportInvalidToken(String matchedPart, String msg) throws IOExce
}
++_inputPtr;
sb.append(c);
if (sb.length() >= MAX_ERROR_TOKEN_LENGTH) {
if (sb.length() >= _ioContext.errorReportConfiguration().getMaxErrorTokenLength()) {
sb.append("...");
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3691,7 +3691,7 @@ protected void _reportInvalidToken(String matchedPart, String msg) throws IOExce
break;
}
sb.append(c);
if (sb.length() >= MAX_ERROR_TOKEN_LENGTH) {
if (sb.length() >= _ioContext.errorReportConfiguration().getMaxErrorTokenLength()) {
sb.append("...");
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ protected JsonToken _finishErrorToken() throws IOException
// 11-Jan-2016, tatu: note: we will fully consume the character,
// included or not, so if recovery was possible, it'd be off-by-one...
_textBuffer.append(ch);
if (_textBuffer.size() < MAX_ERROR_TOKEN_LENGTH) {
if (_textBuffer.size() < _ioContext.errorReportConfiguration().getMaxErrorTokenLength()) {
continue;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.fasterxml.jackson.core;

import com.fasterxml.jackson.core.io.ContentReference;

/**
* Unit tests for class {@link ErrorReportConfiguration#getMaxRawContentLength()}.
*/
public class ErrorReportConfigurationMaxRawContentLengthTest extends BaseTest
{
/*
/**********************************************************
/* Unit Tests
/**********************************************************
*/

public void testBasicToStringErrorConfig()
{
final String three = "three";
// Truncated result
_verifyToString(three, 4,
"[Source: (String)\"thre\"[truncated 1 chars]; line: 1, column: 1]");

// Exact length
_verifyToString(three, 5,
"[Source: (String)\"three\"; line: 1, column: 1]");

// Enough length
_verifyToString(three, 99999,
"[Source: (String)\"three\"; line: 1, column: 1]");
}

/*
/**********************************************************
/* Internal helper methods
/**********************************************************
*/

private void _verifyToString(String rawSrc, int rawContentLength, String expectedMessage)
{
ContentReference reference = _sourceRefWithErrorReportConfig(rawSrc, rawContentLength);
String location = new JsonLocation(reference, 10L, 10L, 1, 1).toString();
assertEquals(expectedMessage, location);
}

private ContentReference _sourceRefWithErrorReportConfig(String rawSrc, int rawContentLength)
{
return _sourceRef(rawSrc,
ErrorReportConfiguration.builder().maxRawContentLength(rawContentLength).build());
}

private ContentReference _sourceRef(String rawSrc, ErrorReportConfiguration errorReportConfiguration)
{
return ContentReference.construct(true, rawSrc, 0, rawSrc.length(),errorReportConfiguration);
}

}