Skip to content

Commit 3eec9de

Browse files
author
Jerry Yang
committed
Implement FasterXML#820
1 parent 5c2ce7a commit 3eec9de

File tree

2 files changed

+131
-22
lines changed

2 files changed

+131
-22
lines changed

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

+74-20
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
package com.fasterxml.jackson.databind;
22

3-
import java.io.*;
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.io.IOException;
6+
import java.io.InputStream;
7+
import java.io.Reader;
48
import java.net.URL;
59
import java.util.Iterator;
610
import java.util.Locale;
711
import java.util.Map;
812
import java.util.TimeZone;
913
import java.util.concurrent.ConcurrentHashMap;
1014

11-
import com.fasterxml.jackson.core.*;
15+
import com.fasterxml.jackson.core.Base64Variant;
16+
import com.fasterxml.jackson.core.FormatSchema;
17+
import com.fasterxml.jackson.core.JsonFactory;
18+
import com.fasterxml.jackson.core.JsonGenerator;
19+
import com.fasterxml.jackson.core.JsonLocation;
20+
import com.fasterxml.jackson.core.JsonParseException;
21+
import com.fasterxml.jackson.core.JsonParser;
22+
import com.fasterxml.jackson.core.JsonProcessingException;
23+
import com.fasterxml.jackson.core.JsonToken;
24+
import com.fasterxml.jackson.core.ObjectCodec;
25+
import com.fasterxml.jackson.core.TreeNode;
26+
import com.fasterxml.jackson.core.Version;
27+
import com.fasterxml.jackson.core.Versioned;
28+
import com.fasterxml.jackson.core.filter.FilteringParserDelegate;
29+
import com.fasterxml.jackson.core.filter.JsonPointerBasedFilter;
30+
import com.fasterxml.jackson.core.filter.TokenFilter;
1231
import com.fasterxml.jackson.core.type.ResolvedType;
1332
import com.fasterxml.jackson.core.type.TypeReference;
1433
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
@@ -38,7 +57,7 @@ public class ObjectReader
3857
implements Versioned, java.io.Serializable // since 2.1
3958
{
4059
private static final long serialVersionUID = 1L; // since 2.5
41-
60+
4261
private final static JavaType JSON_NODE_TYPE = SimpleType.constructUnsafe(JsonNode.class);
4362

4463
/*
@@ -69,6 +88,12 @@ public class ObjectReader
6988
*/
7089
protected final boolean _unwrapRoot;
7190

91+
/**
92+
* Filter to be consider for JsonParser.
93+
* Default value to be null as filter not considered.
94+
*/
95+
private TokenFilter _filter;
96+
7297
/*
7398
/**********************************************************
7499
/* Configuration that can be changed during building
@@ -178,6 +203,7 @@ protected ObjectReader(ObjectMapper mapper, DeserializationConfig config,
178203

179204
_rootDeserializer = _prefetchRootDeserializer(valueType);
180205
_dataFormatReaders = null;
206+
_filter = null;
181207
}
182208

183209
/**
@@ -204,6 +230,7 @@ protected ObjectReader(ObjectReader base, DeserializationConfig config,
204230
_injectableValues = injectableValues;
205231
_unwrapRoot = config.useRootWrapping();
206232
_dataFormatReaders = dataFormatReaders;
233+
_filter = base._filter;
207234
}
208235

209236
/**
@@ -224,6 +251,7 @@ protected ObjectReader(ObjectReader base, DeserializationConfig config)
224251
_injectableValues = base._injectableValues;
225252
_unwrapRoot = config.useRootWrapping();
226253
_dataFormatReaders = base._dataFormatReaders;
254+
_filter = base._filter;
227255
}
228256

229257
protected ObjectReader(ObjectReader base, JsonFactory f)
@@ -243,6 +271,7 @@ protected ObjectReader(ObjectReader base, JsonFactory f)
243271
_injectableValues = base._injectableValues;
244272
_unwrapRoot = base._unwrapRoot;
245273
_dataFormatReaders = base._dataFormatReaders;
274+
_filter = base._filter;
246275
}
247276

248277
/**
@@ -1053,7 +1082,8 @@ public <T> T readValue(InputStream src)
10531082
if (_dataFormatReaders != null) {
10541083
return (T) _detectBindAndClose(_dataFormatReaders.findFormat(src), false);
10551084
}
1056-
return (T) _bindAndClose(_parserFactory.createParser(src));
1085+
1086+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
10571087
}
10581088

10591089
/**
@@ -1069,7 +1099,8 @@ public <T> T readValue(Reader src)
10691099
if (_dataFormatReaders != null) {
10701100
_reportUndetectableSource(src);
10711101
}
1072-
return (T) _bindAndClose(_parserFactory.createParser(src));
1102+
1103+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
10731104
}
10741105

10751106
/**
@@ -1085,7 +1116,8 @@ public <T> T readValue(String src)
10851116
if (_dataFormatReaders != null) {
10861117
_reportUndetectableSource(src);
10871118
}
1088-
return (T) _bindAndClose(_parserFactory.createParser(src));
1119+
1120+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
10891121
}
10901122

10911123
/**
@@ -1101,7 +1133,8 @@ public <T> T readValue(byte[] src)
11011133
if (_dataFormatReaders != null) {
11021134
return (T) _detectBindAndClose(src, 0, src.length);
11031135
}
1104-
return (T) _bindAndClose(_parserFactory.createParser(src));
1136+
1137+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
11051138
}
11061139

11071140
/**
@@ -1117,7 +1150,8 @@ public <T> T readValue(byte[] src, int offset, int length)
11171150
if (_dataFormatReaders != null) {
11181151
return (T) _detectBindAndClose(src, offset, length);
11191152
}
1120-
return (T) _bindAndClose(_parserFactory.createParser(src, offset, length));
1153+
1154+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src, offset, length)));
11211155
}
11221156

11231157
@SuppressWarnings("unchecked")
@@ -1127,7 +1161,8 @@ public <T> T readValue(File src)
11271161
if (_dataFormatReaders != null) {
11281162
return (T) _detectBindAndClose(_dataFormatReaders.findFormat(_inputStream(src)), true);
11291163
}
1130-
return (T) _bindAndClose(_parserFactory.createParser(src));
1164+
1165+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
11311166
}
11321167

11331168
/**
@@ -1143,7 +1178,8 @@ public <T> T readValue(URL src)
11431178
if (_dataFormatReaders != null) {
11441179
return (T) _detectBindAndClose(_dataFormatReaders.findFormat(_inputStream(src)), true);
11451180
}
1146-
return (T) _bindAndClose(_parserFactory.createParser(src));
1181+
1182+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
11471183
}
11481184

11491185
/**
@@ -1160,7 +1196,8 @@ public <T> T readValue(JsonNode src)
11601196
if (_dataFormatReaders != null) {
11611197
_reportUndetectableSource(src);
11621198
}
1163-
return (T) _bindAndClose(treeAsTokens(src));
1199+
1200+
return (T) _bindAndClose(considerFilter(treeAsTokens(src)));
11641201
}
11651202

11661203
/**
@@ -1178,7 +1215,8 @@ public JsonNode readTree(InputStream in)
11781215
if (_dataFormatReaders != null) {
11791216
return _detectBindAndCloseAsTree(in);
11801217
}
1181-
return _bindAndCloseAsTree(_parserFactory.createParser(in));
1218+
1219+
return _bindAndCloseAsTree(considerFilter(_parserFactory.createParser(in)));
11821220
}
11831221

11841222
/**
@@ -1196,7 +1234,8 @@ public JsonNode readTree(Reader r)
11961234
if (_dataFormatReaders != null) {
11971235
_reportUndetectableSource(r);
11981236
}
1199-
return _bindAndCloseAsTree(_parserFactory.createParser(r));
1237+
1238+
return _bindAndCloseAsTree(considerFilter(_parserFactory.createParser(r)));
12001239
}
12011240

12021241
/**
@@ -1214,7 +1253,8 @@ public JsonNode readTree(String json)
12141253
if (_dataFormatReaders != null) {
12151254
_reportUndetectableSource(json);
12161255
}
1217-
return _bindAndCloseAsTree(_parserFactory.createParser(json));
1256+
1257+
return _bindAndCloseAsTree(considerFilter(_parserFactory.createParser(json)));
12181258
}
12191259

12201260
/*
@@ -1268,7 +1308,8 @@ public <T> MappingIterator<T> readValues(InputStream src)
12681308
if (_dataFormatReaders != null) {
12691309
return _detectBindAndReadValues(_dataFormatReaders.findFormat(src), false);
12701310
}
1271-
return _bindAndReadValues(_parserFactory.createParser(src));
1311+
1312+
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
12721313
}
12731314

12741315
/**
@@ -1281,7 +1322,7 @@ public <T> MappingIterator<T> readValues(Reader src)
12811322
if (_dataFormatReaders != null) {
12821323
_reportUndetectableSource(src);
12831324
}
1284-
JsonParser p = _parserFactory.createParser(src);
1325+
JsonParser p = considerFilter(_parserFactory.createParser(src));
12851326
_initForMultiRead(p);
12861327
p.nextToken();
12871328
DeserializationContext ctxt = createDeserializationContext(p);
@@ -1300,7 +1341,7 @@ public <T> MappingIterator<T> readValues(String json)
13001341
if (_dataFormatReaders != null) {
13011342
_reportUndetectableSource(json);
13021343
}
1303-
JsonParser p = _parserFactory.createParser(json);
1344+
JsonParser p = considerFilter(_parserFactory.createParser(json));
13041345
_initForMultiRead(p);
13051346
p.nextToken();
13061347
DeserializationContext ctxt = createDeserializationContext(p);
@@ -1316,7 +1357,7 @@ public <T> MappingIterator<T> readValues(byte[] src, int offset, int length)
13161357
if (_dataFormatReaders != null) {
13171358
return _detectBindAndReadValues(_dataFormatReaders.findFormat(src, offset, length), false);
13181359
}
1319-
return _bindAndReadValues(_parserFactory.createParser(src));
1360+
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
13201361
}
13211362

13221363
/**
@@ -1337,7 +1378,7 @@ public <T> MappingIterator<T> readValues(File src)
13371378
return _detectBindAndReadValues(
13381379
_dataFormatReaders.findFormat(_inputStream(src)), false);
13391380
}
1340-
return _bindAndReadValues(_parserFactory.createParser(src));
1381+
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
13411382
}
13421383

13431384
/**
@@ -1352,7 +1393,7 @@ public <T> MappingIterator<T> readValues(URL src)
13521393
return _detectBindAndReadValues(
13531394
_dataFormatReaders.findFormat(_inputStream(src)), true);
13541395
}
1355-
return _bindAndReadValues(_parserFactory.createParser(src));
1396+
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
13561397
}
13571398

13581399
/*
@@ -1422,6 +1463,14 @@ protected Object _bind(JsonParser p, Object valueToUpdate) throws IOException
14221463
return result;
14231464
}
14241465

1466+
/**
1467+
* Consider filter when creating JsonParser.
1468+
*/
1469+
private JsonParser considerFilter(final JsonParser p) {
1470+
return _filter == null && !FilteringParserDelegate.class.isInstance(p)
1471+
? p : new FilteringParserDelegate(p, _filter, false, false);
1472+
}
1473+
14251474
protected Object _bindAndClose(JsonParser p) throws IOException
14261475
{
14271476
try {
@@ -1734,4 +1783,9 @@ protected JsonDeserializer<Object> _prefetchRootDeserializer(JavaType valueType)
17341783
}
17351784
return deser;
17361785
}
1786+
1787+
public ObjectReader at(final String value) throws JsonParseException, IOException {
1788+
_filter = new JsonPointerBasedFilter(value);
1789+
return this;
1790+
}
17371791
}

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

+57-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
package com.fasterxml.jackson.databind.seq;
22

3-
import com.fasterxml.jackson.core.*;
3+
import java.util.Map;
44

5-
import com.fasterxml.jackson.databind.*;
5+
import com.fasterxml.jackson.core.JsonParser;
6+
import com.fasterxml.jackson.core.JsonProcessingException;
7+
import com.fasterxml.jackson.databind.BaseMapTest;
8+
import com.fasterxml.jackson.databind.JsonNode;
9+
import com.fasterxml.jackson.databind.MappingIterator;
10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
import com.fasterxml.jackson.databind.ObjectReader;
612

713
public class ObjectReaderTest extends BaseMapTest
814
{
915
final ObjectMapper MAPPER = new ObjectMapper();
1016

17+
static class POJO {
18+
public Map<String, Object> name;
19+
}
20+
1121
public void testParserFeatures() throws Exception
1222
{
1323
final String JSON = "[ /* foo */ 7 ]";
@@ -28,4 +38,49 @@ public void testParserFeatures() throws Exception
2838
verifyException(e, "foo");
2939
}
3040
}
41+
42+
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"));
50+
}
51+
52+
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"));
60+
}
61+
62+
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());
70+
}
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());
84+
}
85+
3186
}

0 commit comments

Comments
 (0)