Skip to content

Commit 732cc11

Browse files
committed
Start work on #467
1 parent acda0f9 commit 732cc11

File tree

3 files changed

+277
-2
lines changed

3 files changed

+277
-2
lines changed

src/main/java/com/fasterxml/jackson/core/JsonFactoryBuilder.java

+55-2
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,82 @@
22

33
import com.fasterxml.jackson.core.io.CharacterEscapes;
44
import com.fasterxml.jackson.core.io.SerializedString;
5+
import com.fasterxml.jackson.core.json.JsonReadFeature;
56

67
/**
78
* {@link com.fasterxml.jackson.core.TSFBuilder}
89
* implementation for constructing vanilla {@link JsonFactory}
9-
* instances.
10+
* instances for reading/writing JSON encoded content.
1011
*
11-
* @since 3.0
12+
* @since 2.10
1213
*/
1314
public class JsonFactoryBuilder extends TSFBuilder<JsonFactory, JsonFactoryBuilder>
1415
{
1516
protected CharacterEscapes _characterEscapes;
1617

1718
protected SerializableString _rootValueSeparator;
1819

20+
protected boolean _handleBSONWrappers;
21+
1922
public JsonFactoryBuilder() {
2023
super();
2124
_rootValueSeparator = JsonFactory.DEFAULT_ROOT_VALUE_SEPARATOR;
25+
_handleBSONWrappers = JsonReadFeature.HANDLE_BSON_WRAPPERS.enabledByDefault();
2226
}
2327

2428
public JsonFactoryBuilder(JsonFactory base) {
2529
super(base);
2630
_characterEscapes = base.getCharacterEscapes();
2731
_rootValueSeparator = base._rootValueSeparator;
32+
// _handleBSONWrappers = base._handleBSONWrappers;
33+
}
34+
35+
/*
36+
/**********************************************************
37+
/* Mutators
38+
/**********************************************************
39+
*/
40+
41+
// // // JSON-parsing features
42+
43+
public JsonFactoryBuilder enable(JsonReadFeature f) {
44+
JsonParser.Feature old = f.mappedFeature();
45+
if (old != null) {
46+
enable(old);
47+
} else if (f == JsonReadFeature.HANDLE_BSON_WRAPPERS) {
48+
_handleBSONWrappers = true;
49+
}
50+
return _this();
51+
}
52+
53+
public JsonFactoryBuilder enable(JsonReadFeature first, JsonReadFeature... other) {
54+
enable(first);
55+
for (JsonReadFeature f : other) {
56+
enable(f);
57+
}
58+
return _this();
59+
}
60+
61+
public JsonFactoryBuilder disable(JsonReadFeature f) {
62+
JsonParser.Feature old = f.mappedFeature();
63+
if (old != null) {
64+
disable(old);
65+
} else if (f == JsonReadFeature.HANDLE_BSON_WRAPPERS) {
66+
_handleBSONWrappers = false;
67+
}
68+
return _this();
69+
}
70+
71+
public JsonFactoryBuilder disable(JsonReadFeature first, JsonReadFeature... other) {
72+
disable(first);
73+
for (JsonReadFeature f : other) {
74+
disable(f);
75+
}
76+
return _this();
77+
}
78+
79+
public JsonFactoryBuilder configure(JsonReadFeature f, boolean state) {
80+
return state ? enable(f) : disable(f);
2881
}
2982

3083
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
package com.fasterxml.jackson.core.json;
2+
3+
import com.fasterxml.jackson.core.*;
4+
5+
/**
6+
* Token reader features specific to JSON backend.
7+
*
8+
* @since 2.10
9+
*/
10+
public enum JsonReadFeature
11+
implements FormatFeature
12+
{
13+
// // // Support for non-standard data format constructs: comments
14+
15+
/**
16+
* Feature that determines whether parser will allow use
17+
* of Java/C/C++ style comments (both '/'+'*' and
18+
* '//' varieties) within parsed content or not.
19+
*<p>
20+
* Since JSON specification does not mention comments as legal
21+
* construct,
22+
* this is a non-standard feature; however, in the wild
23+
* this is extensively used. As such, feature is
24+
* <b>disabled by default</b> for parsers and must be
25+
* explicitly enabled.
26+
*/
27+
ALLOW_JAVA_COMMENTS(false, JsonParser.Feature.ALLOW_COMMENTS),
28+
29+
/**
30+
* Feature that determines whether parser will allow use
31+
* of YAML comments, ones starting with '#' and continuing
32+
* until the end of the line. This commenting style is common
33+
* with scripting languages as well.
34+
*<p>
35+
* Since JSON specification does not mention comments as legal
36+
* construct,
37+
* this is a non-standard feature. As such, feature is
38+
* <b>disabled by default</b> for parsers and must be
39+
* explicitly enabled.
40+
*/
41+
ALLOW_YAML_COMMENTS(false, JsonParser.Feature.ALLOW_YAML_COMMENTS),
42+
43+
// // // Support for non-standard data format constructs: quoting/escaping
44+
45+
/**
46+
* Feature that determines whether parser will allow use
47+
* of single quotes (apostrophe, character '\'') for
48+
* quoting Strings (names and String values). If so,
49+
* this is in addition to other acceptable markers.
50+
* but not by JSON specification).
51+
*<p>
52+
* Since JSON specification requires use of double quotes for
53+
* field names,
54+
* this is a non-standard feature, and as such disabled by default.
55+
*/
56+
ALLOW_SINGLE_QUOTES(false, JsonParser.Feature.ALLOW_SINGLE_QUOTES),
57+
58+
/**
59+
* Feature that determines whether parser will allow use
60+
* of unquoted field names (which is allowed by Javascript,
61+
* but not by JSON specification).
62+
*<p>
63+
* Since JSON specification requires use of double quotes for
64+
* field names,
65+
* this is a non-standard feature, and as such disabled by default.
66+
*/
67+
ALLOW_UNQUOTED_FIELD_NAMES(false, JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES),
68+
69+
/**
70+
* Feature that determines whether parser will allow
71+
* JSON Strings to contain unescaped control characters
72+
* (ASCII characters with value less than 32, including
73+
* tab and line feed characters) or not.
74+
* If feature is set false, an exception is thrown if such a
75+
* character is encountered.
76+
*<p>
77+
* Since JSON specification requires quoting for all control characters,
78+
* this is a non-standard feature, and as such disabled by default.
79+
*/
80+
ALLOW_UNESCAPED_CONTROL_CHARS(false, JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS),
81+
82+
/**
83+
* Feature that can be enabled to accept quoting of all character
84+
* using backslash quoting mechanism: if not enabled, only characters
85+
* that are explicitly listed by JSON specification can be thus
86+
* escaped (see JSON spec for small list of these characters)
87+
*<p>
88+
* Since JSON specification requires quoting for all control characters,
89+
* this is a non-standard feature, and as such disabled by default.
90+
*/
91+
ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER(false, JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER),
92+
93+
// // // Support for non-standard data format constructs: number representations
94+
95+
/**
96+
* Feature that determines whether parser will allow
97+
* JSON integral numbers to start with additional (ignorable)
98+
* zeroes (like: 000001). If enabled, no exception is thrown, and extra
99+
* nulls are silently ignored (and not included in textual representation
100+
* exposed via {@link JsonParser#getText}).
101+
*<p>
102+
* Since JSON specification does not allow leading zeroes,
103+
* this is a non-standard feature, and as such disabled by default.
104+
*/
105+
ALLOW_LEADING_ZEROS_FOR_NUMBERS(false, JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS),
106+
107+
/**
108+
* Feature that allows parser to recognize set of
109+
* "Not-a-Number" (NaN) tokens as legal floating number
110+
* values (similar to how many other data formats and
111+
* programming language source code allows it).
112+
* Specific subset contains values that
113+
* <a href="http://www.w3.org/TR/xmlschema-2/">XML Schema</a>
114+
* (see section 3.2.4.1, Lexical Representation)
115+
* allows (tokens are quoted contents, not including quotes):
116+
*<ul>
117+
* <li>"INF" (for positive infinity), as well as alias of "Infinity"
118+
* <li>"-INF" (for negative infinity), alias "-Infinity"
119+
* <li>"NaN" (for other not-a-numbers, like result of division by zero)
120+
*</ul>
121+
*<p>
122+
* Since JSON specification does not allow use of such values,
123+
* this is a non-standard feature, and as such disabled by default.
124+
*/
125+
ALLOW_NON_NUMERIC_NUMBERS(false, JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS),
126+
127+
// // // Support for non-standard data format constructs: array/value separators
128+
129+
/**
130+
* Feature allows the support for "missing" values in a JSON array: missing
131+
* value meaning sequence of two commas, without value in-between but only
132+
* optional white space.
133+
* Enabling this feature will expose "missing" values as {@link JsonToken#VALUE_NULL}
134+
* tokens, which typically become Java nulls in arrays and {@link java.util.Collection}
135+
* in data-binding.
136+
* <p>
137+
* For example, enabling this feature will represent a JSON array <code>["value1",,"value3",]</code>
138+
* as <code>["value1", null, "value3", null]</code>
139+
* <p>
140+
* Since the JSON specification does not allow missing values this is a non-compliant JSON
141+
* feature and is disabled by default.
142+
*/
143+
ALLOW_MISSING_VALUES(false, JsonParser.Feature.ALLOW_MISSING_VALUES),
144+
145+
/**
146+
* Feature that determines whether {@link JsonParser} will allow for a single trailing
147+
* comma following the final value (in an Array) or member (in an Object). These commas
148+
* will simply be ignored.
149+
* <p>
150+
* For example, when this feature is enabled, <code>[true,true,]</code> is equivalent to
151+
* <code>[true, true]</code> and <code>{"a": true,}</code> is equivalent to
152+
* <code>{"a": true}</code>.
153+
* <p>
154+
* When combined with <code>ALLOW_MISSING_VALUES</code>, this feature takes priority, and
155+
* the final trailing comma in an array declaration does not imply a missing
156+
* (<code>null</code>) value. For example, when both <code>ALLOW_MISSING_VALUES</code>
157+
* and <code>ALLOW_TRAILING_COMMA</code> are enabled, <code>[true,true,]</code> is
158+
* equivalent to <code>[true, true]</code>, and <code>[true,true,,]</code> is equivalent to
159+
* <code>[true, true, null]</code>.
160+
* <p>
161+
* Since the JSON specification does not permit trailing commas, this is a non-standard
162+
* feature, and as such disabled by default.
163+
*/
164+
ALLOW_TRAILING_COMMA(false, JsonParser.Feature.ALLOW_TRAILING_COMMA),
165+
166+
// // // Support for non-standard data format constructs: JSON-like formats
167+
168+
/**
169+
* Feature that can be turned on to support handling of BSON "shell mode" JSON extensions
170+
* as specified in {@link href="https://docs.mongodb.com/manual/reference/mongodb-extended-json/"},
171+
* for "shell mode" (but NOT "strict mode" which uses standard JSON syntax but additional
172+
* structural constructs).
173+
*<p>
174+
* NOTE: although attempt is made to support various extension wrappers there is no guarantee that
175+
* all semantic aspects are retained for higher level processing.
176+
*
177+
* @since 2.10
178+
*/
179+
HANDLE_BSON_WRAPPERS(false, null)
180+
;
181+
182+
final private boolean _defaultState;
183+
final private int _mask;
184+
185+
/**
186+
* For backwards compatibility we may need to map to one of existing {@link JsonParser.Feature}s;
187+
* if so, this is the feature to enable/disable.
188+
*/
189+
final private JsonParser.Feature _mappedFeature;
190+
191+
/**
192+
* Method that calculates bit set (flags) of all features that
193+
* are enabled by default.
194+
*/
195+
public static int collectDefaults()
196+
{
197+
int flags = 0;
198+
for (JsonReadFeature f : values()) {
199+
if (f.enabledByDefault()) {
200+
flags |= f.getMask();
201+
}
202+
}
203+
return flags;
204+
}
205+
206+
private JsonReadFeature(boolean defaultState,
207+
JsonParser.Feature mapTo) {
208+
_defaultState = defaultState;
209+
_mask = (1 << ordinal());
210+
_mappedFeature = mapTo;
211+
}
212+
213+
@Override
214+
public boolean enabledByDefault() { return _defaultState; }
215+
@Override
216+
public int getMask() { return _mask; }
217+
@Override
218+
public boolean enabledIn(int flags) { return (flags & _mask) != 0; }
219+
220+
public JsonParser.Feature mappedFeature() { return _mappedFeature; }
221+
}

src/test/java/com/fasterxml/jackson/core/json/async/AsyncTokenFilterTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public void testFilteredNonBlockingParserAllContent() throws IOException
5151
public void testSkipChildrenFailOnSplit() throws IOException
5252
{
5353
NonBlockingJsonParser nbParser = (NonBlockingJsonParser) JSON_F.createNonBlockingByteArrayParser();
54+
@SuppressWarnings("resource")
5455
FilteringParserDelegate filteredParser = new FilteringParserDelegate(nbParser,
5556
TOKEN_FILTER, true, true);
5657
nbParser.feedInput(INPUT_BYTES, 0, 5);

0 commit comments

Comments
 (0)