Skip to content

Commit

Permalink
Start work on #467
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jun 26, 2018
1 parent acda0f9 commit 732cc11
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 2 deletions.
57 changes: 55 additions & 2 deletions src/main/java/com/fasterxml/jackson/core/JsonFactoryBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,82 @@

import com.fasterxml.jackson.core.io.CharacterEscapes;
import com.fasterxml.jackson.core.io.SerializedString;
import com.fasterxml.jackson.core.json.JsonReadFeature;

/**
* {@link com.fasterxml.jackson.core.TSFBuilder}
* implementation for constructing vanilla {@link JsonFactory}
* instances.
* instances for reading/writing JSON encoded content.
*
* @since 3.0
* @since 2.10
*/
public class JsonFactoryBuilder extends TSFBuilder<JsonFactory, JsonFactoryBuilder>
{
protected CharacterEscapes _characterEscapes;

protected SerializableString _rootValueSeparator;

protected boolean _handleBSONWrappers;

public JsonFactoryBuilder() {
super();
_rootValueSeparator = JsonFactory.DEFAULT_ROOT_VALUE_SEPARATOR;
_handleBSONWrappers = JsonReadFeature.HANDLE_BSON_WRAPPERS.enabledByDefault();
}

public JsonFactoryBuilder(JsonFactory base) {
super(base);
_characterEscapes = base.getCharacterEscapes();
_rootValueSeparator = base._rootValueSeparator;
// _handleBSONWrappers = base._handleBSONWrappers;
}

/*
/**********************************************************
/* Mutators
/**********************************************************
*/

// // // JSON-parsing features

public JsonFactoryBuilder enable(JsonReadFeature f) {
JsonParser.Feature old = f.mappedFeature();
if (old != null) {
enable(old);
} else if (f == JsonReadFeature.HANDLE_BSON_WRAPPERS) {
_handleBSONWrappers = true;
}
return _this();
}

public JsonFactoryBuilder enable(JsonReadFeature first, JsonReadFeature... other) {
enable(first);
for (JsonReadFeature f : other) {
enable(f);
}
return _this();
}

public JsonFactoryBuilder disable(JsonReadFeature f) {
JsonParser.Feature old = f.mappedFeature();
if (old != null) {
disable(old);
} else if (f == JsonReadFeature.HANDLE_BSON_WRAPPERS) {
_handleBSONWrappers = false;
}
return _this();
}

public JsonFactoryBuilder disable(JsonReadFeature first, JsonReadFeature... other) {
disable(first);
for (JsonReadFeature f : other) {
disable(f);
}
return _this();
}

public JsonFactoryBuilder configure(JsonReadFeature f, boolean state) {
return state ? enable(f) : disable(f);
}

/**
Expand Down
221 changes: 221 additions & 0 deletions src/main/java/com/fasterxml/jackson/core/json/JsonReadFeature.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package com.fasterxml.jackson.core.json;

import com.fasterxml.jackson.core.*;

/**
* Token reader features specific to JSON backend.
*
* @since 2.10
*/
public enum JsonReadFeature
implements FormatFeature
{
// // // Support for non-standard data format constructs: comments

/**
* Feature that determines whether parser will allow use
* of Java/C/C++ style comments (both '/'+'*' and
* '//' varieties) within parsed content or not.
*<p>
* Since JSON specification does not mention comments as legal
* construct,
* this is a non-standard feature; however, in the wild
* this is extensively used. As such, feature is
* <b>disabled by default</b> for parsers and must be
* explicitly enabled.
*/
ALLOW_JAVA_COMMENTS(false, JsonParser.Feature.ALLOW_COMMENTS),

/**
* Feature that determines whether parser will allow use
* of YAML comments, ones starting with '#' and continuing
* until the end of the line. This commenting style is common
* with scripting languages as well.
*<p>
* Since JSON specification does not mention comments as legal
* construct,
* this is a non-standard feature. As such, feature is
* <b>disabled by default</b> for parsers and must be
* explicitly enabled.
*/
ALLOW_YAML_COMMENTS(false, JsonParser.Feature.ALLOW_YAML_COMMENTS),

// // // Support for non-standard data format constructs: quoting/escaping

/**
* Feature that determines whether parser will allow use
* of single quotes (apostrophe, character '\'') for
* quoting Strings (names and String values). If so,
* this is in addition to other acceptable markers.
* but not by JSON specification).
*<p>
* Since JSON specification requires use of double quotes for
* field names,
* this is a non-standard feature, and as such disabled by default.
*/
ALLOW_SINGLE_QUOTES(false, JsonParser.Feature.ALLOW_SINGLE_QUOTES),

/**
* Feature that determines whether parser will allow use
* of unquoted field names (which is allowed by Javascript,
* but not by JSON specification).
*<p>
* Since JSON specification requires use of double quotes for
* field names,
* this is a non-standard feature, and as such disabled by default.
*/
ALLOW_UNQUOTED_FIELD_NAMES(false, JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES),

/**
* Feature that determines whether parser will allow
* JSON Strings to contain unescaped control characters
* (ASCII characters with value less than 32, including
* tab and line feed characters) or not.
* If feature is set false, an exception is thrown if such a
* character is encountered.
*<p>
* Since JSON specification requires quoting for all control characters,
* this is a non-standard feature, and as such disabled by default.
*/
ALLOW_UNESCAPED_CONTROL_CHARS(false, JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS),

/**
* Feature that can be enabled to accept quoting of all character
* using backslash quoting mechanism: if not enabled, only characters
* that are explicitly listed by JSON specification can be thus
* escaped (see JSON spec for small list of these characters)
*<p>
* Since JSON specification requires quoting for all control characters,
* this is a non-standard feature, and as such disabled by default.
*/
ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER(false, JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER),

// // // Support for non-standard data format constructs: number representations

/**
* Feature that determines whether parser will allow
* JSON integral numbers to start with additional (ignorable)
* zeroes (like: 000001). If enabled, no exception is thrown, and extra
* nulls are silently ignored (and not included in textual representation
* exposed via {@link JsonParser#getText}).
*<p>
* Since JSON specification does not allow leading zeroes,
* this is a non-standard feature, and as such disabled by default.
*/
ALLOW_LEADING_ZEROS_FOR_NUMBERS(false, JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS),

/**
* Feature that allows parser to recognize set of
* "Not-a-Number" (NaN) tokens as legal floating number
* values (similar to how many other data formats and
* programming language source code allows it).
* Specific subset contains values that
* <a href="http://www.w3.org/TR/xmlschema-2/">XML Schema</a>
* (see section 3.2.4.1, Lexical Representation)
* allows (tokens are quoted contents, not including quotes):
*<ul>
* <li>"INF" (for positive infinity), as well as alias of "Infinity"
* <li>"-INF" (for negative infinity), alias "-Infinity"
* <li>"NaN" (for other not-a-numbers, like result of division by zero)
*</ul>
*<p>
* Since JSON specification does not allow use of such values,
* this is a non-standard feature, and as such disabled by default.
*/
ALLOW_NON_NUMERIC_NUMBERS(false, JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS),

// // // Support for non-standard data format constructs: array/value separators

/**
* Feature allows the support for "missing" values in a JSON array: missing
* value meaning sequence of two commas, without value in-between but only
* optional white space.
* Enabling this feature will expose "missing" values as {@link JsonToken#VALUE_NULL}
* tokens, which typically become Java nulls in arrays and {@link java.util.Collection}
* in data-binding.
* <p>
* For example, enabling this feature will represent a JSON array <code>["value1",,"value3",]</code>
* as <code>["value1", null, "value3", null]</code>
* <p>
* Since the JSON specification does not allow missing values this is a non-compliant JSON
* feature and is disabled by default.
*/
ALLOW_MISSING_VALUES(false, JsonParser.Feature.ALLOW_MISSING_VALUES),

/**
* Feature that determines whether {@link JsonParser} will allow for a single trailing
* comma following the final value (in an Array) or member (in an Object). These commas
* will simply be ignored.
* <p>
* For example, when this feature is enabled, <code>[true,true,]</code> is equivalent to
* <code>[true, true]</code> and <code>{"a": true,}</code> is equivalent to
* <code>{"a": true}</code>.
* <p>
* When combined with <code>ALLOW_MISSING_VALUES</code>, this feature takes priority, and
* the final trailing comma in an array declaration does not imply a missing
* (<code>null</code>) value. For example, when both <code>ALLOW_MISSING_VALUES</code>
* and <code>ALLOW_TRAILING_COMMA</code> are enabled, <code>[true,true,]</code> is
* equivalent to <code>[true, true]</code>, and <code>[true,true,,]</code> is equivalent to
* <code>[true, true, null]</code>.
* <p>
* Since the JSON specification does not permit trailing commas, this is a non-standard
* feature, and as such disabled by default.
*/
ALLOW_TRAILING_COMMA(false, JsonParser.Feature.ALLOW_TRAILING_COMMA),

// // // Support for non-standard data format constructs: JSON-like formats

/**
* Feature that can be turned on to support handling of BSON "shell mode" JSON extensions
* as specified in {@link href="https://docs.mongodb.com/manual/reference/mongodb-extended-json/"},
* for "shell mode" (but NOT "strict mode" which uses standard JSON syntax but additional
* structural constructs).
*<p>
* NOTE: although attempt is made to support various extension wrappers there is no guarantee that
* all semantic aspects are retained for higher level processing.
*
* @since 2.10
*/
HANDLE_BSON_WRAPPERS(false, null)
;

final private boolean _defaultState;
final private int _mask;

/**
* For backwards compatibility we may need to map to one of existing {@link JsonParser.Feature}s;
* if so, this is the feature to enable/disable.
*/
final private JsonParser.Feature _mappedFeature;

/**
* Method that calculates bit set (flags) of all features that
* are enabled by default.
*/
public static int collectDefaults()
{
int flags = 0;
for (JsonReadFeature f : values()) {
if (f.enabledByDefault()) {
flags |= f.getMask();
}
}
return flags;
}

private JsonReadFeature(boolean defaultState,
JsonParser.Feature mapTo) {
_defaultState = defaultState;
_mask = (1 << ordinal());
_mappedFeature = mapTo;
}

@Override
public boolean enabledByDefault() { return _defaultState; }
@Override
public int getMask() { return _mask; }
@Override
public boolean enabledIn(int flags) { return (flags & _mask) != 0; }

public JsonParser.Feature mappedFeature() { return _mappedFeature; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public void testFilteredNonBlockingParserAllContent() throws IOException
public void testSkipChildrenFailOnSplit() throws IOException
{
NonBlockingJsonParser nbParser = (NonBlockingJsonParser) JSON_F.createNonBlockingByteArrayParser();
@SuppressWarnings("resource")
FilteringParserDelegate filteredParser = new FilteringParserDelegate(nbParser,
TOKEN_FILTER, true, true);
nbParser.feedInput(INPUT_BYTES, 0, 5);
Expand Down

0 comments on commit 732cc11

Please sign in to comment.