Skip to content

Commit 41be898

Browse files
author
Jerry Yang
committed
Make TokenFilter final in ObjectReader to ensure thread-safety via immutability.
- Some cosmetic changes.
1 parent bc7fa07 commit 41be898

File tree

2 files changed

+98
-67
lines changed

2 files changed

+98
-67
lines changed

src/main/java/com/fasterxml/jackson/databind/ObjectReader.java

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public class ObjectReader
9393
* Filter to be consider for JsonParser.
9494
* Default value to be null as filter not considered.
9595
*/
96-
private TokenFilter _filter;
96+
private final TokenFilter _filter;
9797

9898
/*
9999
/**********************************************************
@@ -275,6 +275,21 @@ protected ObjectReader(ObjectReader base, JsonFactory f)
275275
_filter = base._filter;
276276
}
277277

278+
protected ObjectReader(ObjectReader base, TokenFilter filter) {
279+
_config = base._config;
280+
_context = base._context;
281+
_rootDeserializers = base._rootDeserializers;
282+
_parserFactory = base._parserFactory;
283+
_valueType = base._valueType;
284+
_rootDeserializer = base._rootDeserializer;
285+
_valueToUpdate = base._valueToUpdate;
286+
_schema = base._schema;
287+
_injectableValues = base._injectableValues;
288+
_unwrapRoot = base._unwrapRoot;
289+
_dataFormatReaders = base._dataFormatReaders;
290+
_filter = filter;
291+
}
292+
278293
/**
279294
* Method that will return version information stored in and read from jar
280295
* that contains this class.
@@ -1084,7 +1099,7 @@ public <T> T readValue(InputStream src)
10841099
return (T) _detectBindAndClose(_dataFormatReaders.findFormat(src), false);
10851100
}
10861101

1087-
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
1102+
return (T) _bindAndClose(_considerFilter(_parserFactory.createParser(src)));
10881103
}
10891104

10901105
/**
@@ -1101,7 +1116,7 @@ public <T> T readValue(Reader src)
11011116
_reportUndetectableSource(src);
11021117
}
11031118

1104-
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
1119+
return (T) _bindAndClose(_considerFilter(_parserFactory.createParser(src)));
11051120
}
11061121

11071122
/**
@@ -1118,7 +1133,7 @@ public <T> T readValue(String src)
11181133
_reportUndetectableSource(src);
11191134
}
11201135

1121-
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
1136+
return (T) _bindAndClose(_considerFilter(_parserFactory.createParser(src)));
11221137
}
11231138

11241139
/**
@@ -1135,7 +1150,7 @@ public <T> T readValue(byte[] src)
11351150
return (T) _detectBindAndClose(src, 0, src.length);
11361151
}
11371152

1138-
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
1153+
return (T) _bindAndClose(_considerFilter(_parserFactory.createParser(src)));
11391154
}
11401155

11411156
/**
@@ -1152,7 +1167,7 @@ public <T> T readValue(byte[] src, int offset, int length)
11521167
return (T) _detectBindAndClose(src, offset, length);
11531168
}
11541169

1155-
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src, offset, length)));
1170+
return (T) _bindAndClose(_considerFilter(_parserFactory.createParser(src, offset, length)));
11561171
}
11571172

11581173
@SuppressWarnings("unchecked")
@@ -1163,7 +1178,7 @@ public <T> T readValue(File src)
11631178
return (T) _detectBindAndClose(_dataFormatReaders.findFormat(_inputStream(src)), true);
11641179
}
11651180

1166-
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
1181+
return (T) _bindAndClose(_considerFilter(_parserFactory.createParser(src)));
11671182
}
11681183

11691184
/**
@@ -1180,7 +1195,7 @@ public <T> T readValue(URL src)
11801195
return (T) _detectBindAndClose(_dataFormatReaders.findFormat(_inputStream(src)), true);
11811196
}
11821197

1183-
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
1198+
return (T) _bindAndClose(_considerFilter(_parserFactory.createParser(src)));
11841199
}
11851200

11861201
/**
@@ -1198,7 +1213,7 @@ public <T> T readValue(JsonNode src)
11981213
_reportUndetectableSource(src);
11991214
}
12001215

1201-
return (T) _bindAndClose(considerFilter(treeAsTokens(src)));
1216+
return (T) _bindAndClose(_considerFilter(treeAsTokens(src)));
12021217
}
12031218

12041219
/**
@@ -1217,7 +1232,7 @@ public JsonNode readTree(InputStream in)
12171232
return _detectBindAndCloseAsTree(in);
12181233
}
12191234

1220-
return _bindAndCloseAsTree(considerFilter(_parserFactory.createParser(in)));
1235+
return _bindAndCloseAsTree(_considerFilter(_parserFactory.createParser(in)));
12211236
}
12221237

12231238
/**
@@ -1236,7 +1251,7 @@ public JsonNode readTree(Reader r)
12361251
_reportUndetectableSource(r);
12371252
}
12381253

1239-
return _bindAndCloseAsTree(considerFilter(_parserFactory.createParser(r)));
1254+
return _bindAndCloseAsTree(_considerFilter(_parserFactory.createParser(r)));
12401255
}
12411256

12421257
/**
@@ -1255,7 +1270,7 @@ public JsonNode readTree(String json)
12551270
_reportUndetectableSource(json);
12561271
}
12571272

1258-
return _bindAndCloseAsTree(considerFilter(_parserFactory.createParser(json)));
1273+
return _bindAndCloseAsTree(_considerFilter(_parserFactory.createParser(json)));
12591274
}
12601275

12611276
/*
@@ -1310,7 +1325,7 @@ public <T> MappingIterator<T> readValues(InputStream src)
13101325
return _detectBindAndReadValues(_dataFormatReaders.findFormat(src), false);
13111326
}
13121327

1313-
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
1328+
return _bindAndReadValues(_considerFilter(_parserFactory.createParser(src)));
13141329
}
13151330

13161331
/**
@@ -1323,7 +1338,7 @@ public <T> MappingIterator<T> readValues(Reader src)
13231338
if (_dataFormatReaders != null) {
13241339
_reportUndetectableSource(src);
13251340
}
1326-
JsonParser p = considerFilter(_parserFactory.createParser(src));
1341+
JsonParser p = _considerFilter(_parserFactory.createParser(src));
13271342
_initForMultiRead(p);
13281343
p.nextToken();
13291344
DeserializationContext ctxt = createDeserializationContext(p);
@@ -1342,7 +1357,7 @@ public <T> MappingIterator<T> readValues(String json)
13421357
if (_dataFormatReaders != null) {
13431358
_reportUndetectableSource(json);
13441359
}
1345-
JsonParser p = considerFilter(_parserFactory.createParser(json));
1360+
JsonParser p = _considerFilter(_parserFactory.createParser(json));
13461361
_initForMultiRead(p);
13471362
p.nextToken();
13481363
DeserializationContext ctxt = createDeserializationContext(p);
@@ -1358,7 +1373,7 @@ public <T> MappingIterator<T> readValues(byte[] src, int offset, int length)
13581373
if (_dataFormatReaders != null) {
13591374
return _detectBindAndReadValues(_dataFormatReaders.findFormat(src, offset, length), false);
13601375
}
1361-
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
1376+
return _bindAndReadValues(_considerFilter(_parserFactory.createParser(src)));
13621377
}
13631378

13641379
/**
@@ -1379,7 +1394,7 @@ public <T> MappingIterator<T> readValues(File src)
13791394
return _detectBindAndReadValues(
13801395
_dataFormatReaders.findFormat(_inputStream(src)), false);
13811396
}
1382-
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
1397+
return _bindAndReadValues(_considerFilter(_parserFactory.createParser(src)));
13831398
}
13841399

13851400
/**
@@ -1394,7 +1409,7 @@ public <T> MappingIterator<T> readValues(URL src)
13941409
return _detectBindAndReadValues(
13951410
_dataFormatReaders.findFormat(_inputStream(src)), true);
13961411
}
1397-
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
1412+
return _bindAndReadValues(_considerFilter(_parserFactory.createParser(src)));
13981413
}
13991414

14001415
/*
@@ -1467,9 +1482,9 @@ protected Object _bind(JsonParser p, Object valueToUpdate) throws IOException
14671482
/**
14681483
* Consider filter when creating JsonParser.
14691484
*/
1470-
private JsonParser considerFilter(final JsonParser p) {
1471-
return _filter == null || FilteringParserDelegate.class.isInstance(p)
1472-
? p : new FilteringParserDelegate(p, _filter, false, false);
1485+
protected JsonParser _considerFilter(final JsonParser p) {
1486+
return _filter == null || FilteringParserDelegate.class.isInstance(p)
1487+
? p : new FilteringParserDelegate(p, _filter, false, false);
14731488
}
14741489

14751490
protected Object _bindAndClose(JsonParser p) throws IOException
@@ -1790,19 +1805,16 @@ protected JsonDeserializer<Object> _prefetchRootDeserializer(JavaType valueType)
17901805
* {@link JsonPointerBasedFilter} is registered and will be used for parsing later.
17911806
* @since 2.6
17921807
*/
1793-
public ObjectReader at(final String value) {
1794-
_filter = new JsonPointerBasedFilter(value);
1795-
return this;
1796-
}
1808+
public ObjectReader at(final String value) {
1809+
return new ObjectReader(this, new JsonPointerBasedFilter(value));
1810+
}
17971811

17981812
/**
17991813
* Convenience method to bind from {@link JsonPointer}
18001814
* {@link JsonPointerBasedFilter} is registered and will be used for parsing later.
18011815
* @since 2.6
18021816
*/
1803-
public ObjectReader at(final JsonPointer pointer) {
1804-
_filter = new JsonPointerBasedFilter(pointer);
1805-
return this;
1806-
}
1807-
1817+
public ObjectReader at(final JsonPointer pointer) {
1818+
return new ObjectReader(this, new JsonPointerBasedFilter(pointer));
1819+
}
18081820
}

src/test/java/com/fasterxml/jackson/databind/seq/ObjectReaderTest.java

Lines changed: 56 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class ObjectReaderTest extends BaseMapTest
1515
final ObjectMapper MAPPER = new ObjectMapper();
1616

1717
static class POJO {
18-
public Map<String, Object> name;
18+
public Map<String, Object> name;
1919
}
2020

2121
public void testParserFeatures() throws Exception
@@ -40,47 +40,66 @@ public void testParserFeatures() throws Exception
4040
}
4141

4242
public void testNoPointerLoading() throws Exception {
43-
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
44-
45-
JsonNode tree = MAPPER.readTree(source);
46-
JsonNode node = tree.at("/foo/bar/caller");
47-
POJO pojo = MAPPER.treeToValue(node, POJO.class);
48-
assertTrue(pojo.name.containsKey("value"));
49-
assertEquals(1234, pojo.name.get("value"));
43+
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
44+
45+
JsonNode tree = MAPPER.readTree(source);
46+
JsonNode node = tree.at("/foo/bar/caller");
47+
POJO pojo = MAPPER.treeToValue(node, POJO.class);
48+
assertTrue(pojo.name.containsKey("value"));
49+
assertEquals(1234, pojo.name.get("value"));
5050
}
51-
51+
5252
public void testPointerLoading() throws Exception {
53-
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
54-
55-
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
56-
57-
POJO pojo = reader.readValue(source);
58-
assertTrue(pojo.name.containsKey("value"));
59-
assertEquals(1234, pojo.name.get("value"));
53+
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
54+
55+
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
56+
57+
POJO pojo = reader.readValue(source);
58+
assertTrue(pojo.name.containsKey("value"));
59+
assertEquals(1234, pojo.name.get("value"));
6060
}
61-
61+
6262
public void testPointerLoadingAsJsonNode() throws Exception {
63-
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
64-
65-
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
66-
67-
JsonNode node = reader.readTree(source);
68-
assertTrue(node.has("name"));
69-
assertEquals("{\"value\":1234}", node.get("name").toString());
63+
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
64+
65+
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
66+
67+
JsonNode node = reader.readTree(source);
68+
assertTrue(node.has("name"));
69+
assertEquals("{\"value\":1234}", node.get("name").toString());
7070
}
71-
72-
public void testPointerLoadingMappingIterator() throws Exception {
73-
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
74-
75-
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
76-
77-
MappingIterator<POJO> itr = reader.readValues(source);
78-
79-
POJO pojo = itr.next();
80-
81-
assertTrue(pojo.name.containsKey("value"));
82-
assertEquals(1234, pojo.name.get("value"));
83-
assertFalse(itr.hasNext());
71+
72+
public void testPointerLoadingMappingIteratorOne() throws Exception {
73+
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
74+
75+
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
76+
77+
MappingIterator<POJO> itr = reader.readValues(source);
78+
79+
POJO pojo = itr.next();
80+
81+
assertTrue(pojo.name.containsKey("value"));
82+
assertEquals(1234, pojo.name.get("value"));
83+
assertFalse(itr.hasNext());
8484
}
85+
86+
public void testPointerLoadingMappingIteratorMany() throws Exception {
87+
final String source = "{\"foo\":{\"bar\":{\"caller\":[{\"name\":{\"value\":1234}}, {\"name\":{\"value\":5678}}]}}}";
8588

89+
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
90+
91+
MappingIterator<POJO> itr = reader.readValues(source);
92+
93+
POJO pojo = itr.next();
94+
95+
assertTrue(pojo.name.containsKey("value"));
96+
assertEquals(1234, pojo.name.get("value"));
97+
assertTrue(itr.hasNext());
98+
99+
pojo = itr.next();
100+
101+
assertTrue(pojo.name.containsKey("value"));
102+
assertEquals(5678, pojo.name.get("value"));
103+
assertFalse(itr.hasNext());
104+
}
86105
}

0 commit comments

Comments
 (0)