Skip to content

Commit 4e7afc4

Browse files
author
Jerry Yang
committed
Implement #820
1 parent 5c2ce7a commit 4e7afc4

File tree

2 files changed

+148
-22
lines changed

2 files changed

+148
-22
lines changed

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

+91-20
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,34 @@
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.JsonPointer;
23+
import com.fasterxml.jackson.core.JsonProcessingException;
24+
import com.fasterxml.jackson.core.JsonToken;
25+
import com.fasterxml.jackson.core.ObjectCodec;
26+
import com.fasterxml.jackson.core.TreeNode;
27+
import com.fasterxml.jackson.core.Version;
28+
import com.fasterxml.jackson.core.Versioned;
29+
import com.fasterxml.jackson.core.filter.FilteringParserDelegate;
30+
import com.fasterxml.jackson.core.filter.JsonPointerBasedFilter;
31+
import com.fasterxml.jackson.core.filter.TokenFilter;
1232
import com.fasterxml.jackson.core.type.ResolvedType;
1333
import com.fasterxml.jackson.core.type.TypeReference;
1434
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
@@ -38,7 +58,7 @@ public class ObjectReader
3858
implements Versioned, java.io.Serializable // since 2.1
3959
{
4060
private static final long serialVersionUID = 1L; // since 2.5
41-
61+
4262
private final static JavaType JSON_NODE_TYPE = SimpleType.constructUnsafe(JsonNode.class);
4363

4464
/*
@@ -69,6 +89,12 @@ public class ObjectReader
6989
*/
7090
protected final boolean _unwrapRoot;
7191

92+
/**
93+
* Filter to be consider for JsonParser.
94+
* Default value to be null as filter not considered.
95+
*/
96+
private TokenFilter _filter;
97+
7298
/*
7399
/**********************************************************
74100
/* Configuration that can be changed during building
@@ -178,6 +204,7 @@ protected ObjectReader(ObjectMapper mapper, DeserializationConfig config,
178204

179205
_rootDeserializer = _prefetchRootDeserializer(valueType);
180206
_dataFormatReaders = null;
207+
_filter = null;
181208
}
182209

183210
/**
@@ -204,6 +231,7 @@ protected ObjectReader(ObjectReader base, DeserializationConfig config,
204231
_injectableValues = injectableValues;
205232
_unwrapRoot = config.useRootWrapping();
206233
_dataFormatReaders = dataFormatReaders;
234+
_filter = base._filter;
207235
}
208236

209237
/**
@@ -224,6 +252,7 @@ protected ObjectReader(ObjectReader base, DeserializationConfig config)
224252
_injectableValues = base._injectableValues;
225253
_unwrapRoot = config.useRootWrapping();
226254
_dataFormatReaders = base._dataFormatReaders;
255+
_filter = base._filter;
227256
}
228257

229258
protected ObjectReader(ObjectReader base, JsonFactory f)
@@ -243,6 +272,7 @@ protected ObjectReader(ObjectReader base, JsonFactory f)
243272
_injectableValues = base._injectableValues;
244273
_unwrapRoot = base._unwrapRoot;
245274
_dataFormatReaders = base._dataFormatReaders;
275+
_filter = base._filter;
246276
}
247277

248278
/**
@@ -1053,7 +1083,8 @@ public <T> T readValue(InputStream src)
10531083
if (_dataFormatReaders != null) {
10541084
return (T) _detectBindAndClose(_dataFormatReaders.findFormat(src), false);
10551085
}
1056-
return (T) _bindAndClose(_parserFactory.createParser(src));
1086+
1087+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
10571088
}
10581089

10591090
/**
@@ -1069,7 +1100,8 @@ public <T> T readValue(Reader src)
10691100
if (_dataFormatReaders != null) {
10701101
_reportUndetectableSource(src);
10711102
}
1072-
return (T) _bindAndClose(_parserFactory.createParser(src));
1103+
1104+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
10731105
}
10741106

10751107
/**
@@ -1085,7 +1117,8 @@ public <T> T readValue(String src)
10851117
if (_dataFormatReaders != null) {
10861118
_reportUndetectableSource(src);
10871119
}
1088-
return (T) _bindAndClose(_parserFactory.createParser(src));
1120+
1121+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
10891122
}
10901123

10911124
/**
@@ -1101,7 +1134,8 @@ public <T> T readValue(byte[] src)
11011134
if (_dataFormatReaders != null) {
11021135
return (T) _detectBindAndClose(src, 0, src.length);
11031136
}
1104-
return (T) _bindAndClose(_parserFactory.createParser(src));
1137+
1138+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
11051139
}
11061140

11071141
/**
@@ -1117,7 +1151,8 @@ public <T> T readValue(byte[] src, int offset, int length)
11171151
if (_dataFormatReaders != null) {
11181152
return (T) _detectBindAndClose(src, offset, length);
11191153
}
1120-
return (T) _bindAndClose(_parserFactory.createParser(src, offset, length));
1154+
1155+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src, offset, length)));
11211156
}
11221157

11231158
@SuppressWarnings("unchecked")
@@ -1127,7 +1162,8 @@ public <T> T readValue(File src)
11271162
if (_dataFormatReaders != null) {
11281163
return (T) _detectBindAndClose(_dataFormatReaders.findFormat(_inputStream(src)), true);
11291164
}
1130-
return (T) _bindAndClose(_parserFactory.createParser(src));
1165+
1166+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
11311167
}
11321168

11331169
/**
@@ -1143,7 +1179,8 @@ public <T> T readValue(URL src)
11431179
if (_dataFormatReaders != null) {
11441180
return (T) _detectBindAndClose(_dataFormatReaders.findFormat(_inputStream(src)), true);
11451181
}
1146-
return (T) _bindAndClose(_parserFactory.createParser(src));
1182+
1183+
return (T) _bindAndClose(considerFilter(_parserFactory.createParser(src)));
11471184
}
11481185

11491186
/**
@@ -1160,7 +1197,8 @@ public <T> T readValue(JsonNode src)
11601197
if (_dataFormatReaders != null) {
11611198
_reportUndetectableSource(src);
11621199
}
1163-
return (T) _bindAndClose(treeAsTokens(src));
1200+
1201+
return (T) _bindAndClose(considerFilter(treeAsTokens(src)));
11641202
}
11651203

11661204
/**
@@ -1178,7 +1216,8 @@ public JsonNode readTree(InputStream in)
11781216
if (_dataFormatReaders != null) {
11791217
return _detectBindAndCloseAsTree(in);
11801218
}
1181-
return _bindAndCloseAsTree(_parserFactory.createParser(in));
1219+
1220+
return _bindAndCloseAsTree(considerFilter(_parserFactory.createParser(in)));
11821221
}
11831222

11841223
/**
@@ -1196,7 +1235,8 @@ public JsonNode readTree(Reader r)
11961235
if (_dataFormatReaders != null) {
11971236
_reportUndetectableSource(r);
11981237
}
1199-
return _bindAndCloseAsTree(_parserFactory.createParser(r));
1238+
1239+
return _bindAndCloseAsTree(considerFilter(_parserFactory.createParser(r)));
12001240
}
12011241

12021242
/**
@@ -1214,7 +1254,8 @@ public JsonNode readTree(String json)
12141254
if (_dataFormatReaders != null) {
12151255
_reportUndetectableSource(json);
12161256
}
1217-
return _bindAndCloseAsTree(_parserFactory.createParser(json));
1257+
1258+
return _bindAndCloseAsTree(considerFilter(_parserFactory.createParser(json)));
12181259
}
12191260

12201261
/*
@@ -1268,7 +1309,8 @@ public <T> MappingIterator<T> readValues(InputStream src)
12681309
if (_dataFormatReaders != null) {
12691310
return _detectBindAndReadValues(_dataFormatReaders.findFormat(src), false);
12701311
}
1271-
return _bindAndReadValues(_parserFactory.createParser(src));
1312+
1313+
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
12721314
}
12731315

12741316
/**
@@ -1281,7 +1323,7 @@ public <T> MappingIterator<T> readValues(Reader src)
12811323
if (_dataFormatReaders != null) {
12821324
_reportUndetectableSource(src);
12831325
}
1284-
JsonParser p = _parserFactory.createParser(src);
1326+
JsonParser p = considerFilter(_parserFactory.createParser(src));
12851327
_initForMultiRead(p);
12861328
p.nextToken();
12871329
DeserializationContext ctxt = createDeserializationContext(p);
@@ -1300,7 +1342,7 @@ public <T> MappingIterator<T> readValues(String json)
13001342
if (_dataFormatReaders != null) {
13011343
_reportUndetectableSource(json);
13021344
}
1303-
JsonParser p = _parserFactory.createParser(json);
1345+
JsonParser p = considerFilter(_parserFactory.createParser(json));
13041346
_initForMultiRead(p);
13051347
p.nextToken();
13061348
DeserializationContext ctxt = createDeserializationContext(p);
@@ -1316,7 +1358,7 @@ public <T> MappingIterator<T> readValues(byte[] src, int offset, int length)
13161358
if (_dataFormatReaders != null) {
13171359
return _detectBindAndReadValues(_dataFormatReaders.findFormat(src, offset, length), false);
13181360
}
1319-
return _bindAndReadValues(_parserFactory.createParser(src));
1361+
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
13201362
}
13211363

13221364
/**
@@ -1337,7 +1379,7 @@ public <T> MappingIterator<T> readValues(File src)
13371379
return _detectBindAndReadValues(
13381380
_dataFormatReaders.findFormat(_inputStream(src)), false);
13391381
}
1340-
return _bindAndReadValues(_parserFactory.createParser(src));
1382+
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
13411383
}
13421384

13431385
/**
@@ -1352,7 +1394,7 @@ public <T> MappingIterator<T> readValues(URL src)
13521394
return _detectBindAndReadValues(
13531395
_dataFormatReaders.findFormat(_inputStream(src)), true);
13541396
}
1355-
return _bindAndReadValues(_parserFactory.createParser(src));
1397+
return _bindAndReadValues(considerFilter(_parserFactory.createParser(src)));
13561398
}
13571399

13581400
/*
@@ -1422,6 +1464,14 @@ protected Object _bind(JsonParser p, Object valueToUpdate) throws IOException
14221464
return result;
14231465
}
14241466

1467+
/**
1468+
* Consider filter when creating JsonParser.
1469+
*/
1470+
private JsonParser considerFilter(final JsonParser p) {
1471+
return _filter == null && !FilteringParserDelegate.class.isInstance(p)
1472+
? p : new FilteringParserDelegate(p, _filter, false, false);
1473+
}
1474+
14251475
protected Object _bindAndClose(JsonParser p) throws IOException
14261476
{
14271477
try {
@@ -1734,4 +1784,25 @@ protected JsonDeserializer<Object> _prefetchRootDeserializer(JavaType valueType)
17341784
}
17351785
return deser;
17361786
}
1787+
1788+
/**
1789+
* Convenience method to bind from {@link JsonPointer}.
1790+
* {@link JsonPointerBasedFilter} is registered and will be used for parsing later.
1791+
* @since 2.6
1792+
*/
1793+
public ObjectReader at(final String value) {
1794+
_filter = new JsonPointerBasedFilter(value);
1795+
return this;
1796+
}
1797+
1798+
/**
1799+
* Convenience method to bind from {@link JsonPointer}
1800+
* {@link JsonPointerBasedFilter} is registered and will be used for parsing later.
1801+
* @since 2.6
1802+
*/
1803+
public ObjectReader at(final JsonPointer pointer) {
1804+
_filter = new JsonPointerBasedFilter(pointer);
1805+
return this;
1806+
}
1807+
17371808
}

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)