Skip to content

Commit b014bee

Browse files
authored
#2013: add support for reading from / writing to a Path (#3066)
1 parent 733b8d6 commit b014bee

File tree

6 files changed

+1448
-5
lines changed

6 files changed

+1448
-5
lines changed

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

+132
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.*;
44
import java.lang.reflect.Type;
55
import java.net.URL;
6+
import java.nio.file.Path;
67
import java.text.DateFormat;
78
import java.util.Collection;
89
import java.util.List;
@@ -583,6 +584,20 @@ public JsonParser createParser(File src) throws JacksonException {
583584
return ctxt.assignAndReturnParser(_streamFactory.createParser(ctxt, src));
584585
}
585586

587+
/**
588+
* Factory method for constructing {@link JsonParser} that is properly
589+
* wired to allow callbacks for deserialization: basically
590+
* constructs a {@link ObjectReadContext} and then calls
591+
* {@link TokenStreamFactory#createParser(ObjectReadContext,Path)}.
592+
*
593+
* @since 3.0
594+
*/
595+
public JsonParser createParser(Path src) throws JacksonException {
596+
_assertNotNull("src", src);
597+
DeserializationContextExt ctxt = _deserializationContext();
598+
return ctxt.assignAndReturnParser(_streamFactory.createParser(ctxt, src));
599+
}
600+
586601
/**
587602
* Factory method for constructing {@link JsonParser} that is properly
588603
* wired to allow callbacks for deserialization: basically
@@ -781,6 +796,19 @@ public JsonGenerator createGenerator(File f, JsonEncoding enc) throws JacksonExc
781796
return _streamFactory.createGenerator(_serializerProvider(), f, enc);
782797
}
783798

799+
/**
800+
* Factory method for constructing {@link JsonGenerator} that is properly
801+
* wired to allow callbacks for serialization: basically
802+
* constructs a {@link ObjectWriteContext} and then calls
803+
* {@link TokenStreamFactory#createGenerator(ObjectWriteContext,Path,JsonEncoding)}.
804+
*
805+
* @since 3.0
806+
*/
807+
public JsonGenerator createGenerator(Path p, JsonEncoding enc) throws JacksonException {
808+
_assertNotNull("p", p);
809+
return _streamFactory.createGenerator(_serializerProvider(), p, enc);
810+
}
811+
784812
/**
785813
* Factory method for constructing {@link JsonGenerator} that is properly
786814
* wired to allow callbacks for serialization: basically
@@ -1151,6 +1179,19 @@ public JsonNode readTree(File file) throws JacksonException
11511179
return _readTreeAndClose(ctxt, _streamFactory.createParser(ctxt, file));
11521180
}
11531181

1182+
/**
1183+
* Same as {@link #readTree(InputStream)} except content read from
1184+
* passed-in {@link Path}.
1185+
*
1186+
* @since 3.0
1187+
*/
1188+
public JsonNode readTree(Path path) throws JacksonException
1189+
{
1190+
_assertNotNull("path", path);
1191+
DeserializationContextExt ctxt = _deserializationContext();
1192+
return _readTreeAndClose(ctxt, _streamFactory.createParser(ctxt, path));
1193+
}
1194+
11541195
/**
11551196
* Same as {@link #readTree(InputStream)} except content read from
11561197
* passed-in {@link URL}.
@@ -1365,6 +1406,74 @@ public <T> T readValue(File src, JavaType valueType) throws JacksonException
13651406
return (T) _readMapAndClose(ctxt, _streamFactory.createParser(ctxt, src), valueType);
13661407
}
13671408

1409+
/**
1410+
* Method to deserialize JSON content from given path into given Java type.
1411+
*
1412+
* @throws WrappedIOException if a low-level I/O problem (unexpected end-of-input,
1413+
* network error) occurs (passed through as-is without additional wrapping -- note
1414+
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
1415+
* does NOT result in wrapping of exception even if enabled)
1416+
* @throws StreamReadException if underlying input contains invalid content
1417+
* of type {@link JsonParser} supports (JSON for default case)
1418+
* @throws DatabindException if the input JSON structure does not match structure
1419+
* expected for result type (or has other mismatch issues)
1420+
*
1421+
* @since 3.0
1422+
*/
1423+
@SuppressWarnings("unchecked")
1424+
public <T> T readValue(Path src, Class<T> valueType) throws JacksonException
1425+
{
1426+
_assertNotNull("src", src);
1427+
DeserializationContextExt ctxt = _deserializationContext();
1428+
return (T) _readMapAndClose(ctxt, _streamFactory.createParser(ctxt, src),
1429+
_typeFactory.constructType(valueType));
1430+
}
1431+
1432+
/**
1433+
* Method to deserialize JSON content from given path into given Java type.
1434+
*
1435+
* @throws WrappedIOException if a low-level I/O problem (unexpected end-of-input,
1436+
* network error) occurs (passed through as-is without additional wrapping -- note
1437+
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
1438+
* does NOT result in wrapping of exception even if enabled)
1439+
* @throws StreamReadException if underlying input contains invalid content
1440+
* of type {@link JsonParser} supports (JSON for default case)
1441+
* @throws DatabindException if the input JSON structure does not match structure
1442+
* expected for result type (or has other mismatch issues)
1443+
*
1444+
* @since 3.0
1445+
*/
1446+
@SuppressWarnings({ "unchecked" })
1447+
public <T> T readValue(Path src, TypeReference<T> valueTypeRef) throws JacksonException
1448+
{
1449+
_assertNotNull("src", src);
1450+
DeserializationContextExt ctxt = _deserializationContext();
1451+
return (T) _readMapAndClose(ctxt, _streamFactory.createParser(ctxt, src),
1452+
_typeFactory.constructType(valueTypeRef));
1453+
}
1454+
1455+
/**
1456+
* Method to deserialize JSON content from given path into given Java type.
1457+
*
1458+
* @throws WrappedIOException if a low-level I/O problem (unexpected end-of-input,
1459+
* network error) occurs (passed through as-is without additional wrapping -- note
1460+
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
1461+
* does NOT result in wrapping of exception even if enabled)
1462+
* @throws StreamReadException if underlying input contains invalid content
1463+
* of type {@link JsonParser} supports (JSON for default case)
1464+
* @throws DatabindException if the input JSON structure does not match structure
1465+
* expected for result type (or has other mismatch issues)
1466+
*
1467+
* @since 3.0
1468+
*/
1469+
@SuppressWarnings("unchecked")
1470+
public <T> T readValue(Path src, JavaType valueType) throws JacksonException
1471+
{
1472+
_assertNotNull("src", src);
1473+
DeserializationContextExt ctxt = _deserializationContext();
1474+
return (T) _readMapAndClose(ctxt, _streamFactory.createParser(ctxt, src), valueType);
1475+
}
1476+
13681477
/**
13691478
* Method to deserialize JSON content from given resource into given Java type.
13701479
*<p>
@@ -1610,6 +1719,15 @@ public <T> T readValue(DataInput src, JavaType valueType) throws JacksonExceptio
16101719
_streamFactory.createParser(ctxt, src), valueType);
16111720
}
16121721

1722+
@SuppressWarnings("unchecked")
1723+
public <T> T readValue(DataInput src, TypeReference<T> valueTypeRef) throws JacksonException
1724+
{
1725+
_assertNotNull("src", src);
1726+
DeserializationContextExt ctxt = _deserializationContext();
1727+
return (T) _readMapAndClose(ctxt,
1728+
_streamFactory.createParser(ctxt, src), _typeFactory.constructType(valueTypeRef));
1729+
}
1730+
16131731
/*
16141732
/**********************************************************************
16151733
/* Public API: serialization (mapping from Java types to external format)
@@ -1628,6 +1746,20 @@ public void writeValue(File file, Object value) throws JacksonException
16281746
_streamFactory.createGenerator(prov, file, JsonEncoding.UTF8), value);
16291747
}
16301748

1749+
/**
1750+
* Method that can be used to serialize any Java value as
1751+
* JSON output, written to Path provided.
1752+
*
1753+
* @since 3.0
1754+
*/
1755+
public void writeValue(Path path, Object value) throws JacksonException
1756+
{
1757+
_assertNotNull("path", path);
1758+
SerializationContextExt prov = _serializerProvider();
1759+
_configAndWriteValue(prov,
1760+
_streamFactory.createGenerator(prov, path, JsonEncoding.UTF8), value);
1761+
}
1762+
16311763
/**
16321764
* Method that can be used to serialize any Java value as
16331765
* JSON output, using output stream provided (using encoding

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

+56
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.io.*;
44
import java.net.URL;
5+
import java.nio.file.Files;
6+
import java.nio.file.Path;
57
import java.util.*;
68
import java.util.concurrent.ConcurrentHashMap;
79

@@ -773,6 +775,20 @@ public JsonParser createParser(File src) throws JacksonException {
773775
return ctxt.assignAndReturnParser(_parserFactory.createParser(ctxt, src));
774776
}
775777

778+
/**
779+
* Factory method for constructing {@link JsonParser} that is properly
780+
* wired to allow callbacks for deserialization: basically
781+
* constructs a {@link ObjectReadContext} and then calls
782+
* {@link TokenStreamFactory#createParser(ObjectReadContext,Path)}.
783+
*
784+
* @since 3.0
785+
*/
786+
public JsonParser createParser(Path src) throws JacksonException {
787+
_assertNotNull("src", src);
788+
DeserializationContextExt ctxt = _deserializationContext();
789+
return ctxt.assignAndReturnParser(_parserFactory.createParser(ctxt, src));
790+
}
791+
776792
/**
777793
* Factory method for constructing {@link JsonParser} that is properly
778794
* wired to allow callbacks for deserialization: basically
@@ -1202,6 +1218,25 @@ public <T> T readValue(File f) throws JacksonException
12021218
_considerFilter(_parserFactory.createParser(ctxt, f), false));
12031219
}
12041220

1221+
/**
1222+
* Method that binds content read from given {@link Path}
1223+
* using configuration of this reader.
1224+
* Value return is either newly constructed, or root value that
1225+
* was specified with {@link #withValueToUpdate(Object)}.
1226+
*
1227+
* @param p Path that contains content to read
1228+
*
1229+
* @since 3.0
1230+
*/
1231+
@SuppressWarnings("unchecked")
1232+
public <T> T readValue(Path p) throws JacksonException
1233+
{
1234+
_assertNotNull("p", p);
1235+
DeserializationContextExt ctxt = _deserializationContext();
1236+
return (T) _bindAndClose(ctxt,
1237+
_considerFilter(_parserFactory.createParser(ctxt, p), false));
1238+
}
1239+
12051240
/**
12061241
* Method that binds content read from given input source,
12071242
* using configuration of this reader.
@@ -1456,6 +1491,19 @@ public <T> MappingIterator<T> readValues(File src) throws JacksonException
14561491
_considerFilter(_parserFactory.createParser(ctxt, src), true));
14571492
}
14581493

1494+
/**
1495+
* Overloaded version of {@link #readValues(InputStream)}.
1496+
*
1497+
* @since 3.0
1498+
*/
1499+
public <T> MappingIterator<T> readValues(Path src) throws JacksonException
1500+
{
1501+
_assertNotNull("src", src);
1502+
DeserializationContextExt ctxt = _deserializationContext();
1503+
return _bindAndReadValues(ctxt,
1504+
_considerFilter(_parserFactory.createParser(ctxt, src), true));
1505+
}
1506+
14591507
/**
14601508
* Overloaded version of {@link #readValue(InputStream)}.
14611509
*<p>
@@ -1701,6 +1749,14 @@ protected InputStream _inputStream(File f) throws JacksonException {
17011749
}
17021750
}
17031751

1752+
protected InputStream _inputStream(Path p) throws JacksonException {
1753+
try {
1754+
return Files.newInputStream(p);
1755+
} catch (IOException e) {
1756+
throw WrappedIOException.construct(e);
1757+
}
1758+
}
1759+
17041760
protected final void _assertNotNull(String paramName, Object src) {
17051761
if (src == null){
17061762
throw new IllegalArgumentException(String.format("argument \"%s\" is null", paramName));

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

+75
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.fasterxml.jackson.databind;
22

33
import java.io.*;
4+
import java.nio.file.Path;
45
import java.text.*;
56
import java.util.Locale;
67
import java.util.Map;
@@ -569,6 +570,19 @@ public JsonGenerator createGenerator(File target, JsonEncoding enc) {
569570
return _generatorFactory.createGenerator(_serializerProvider(), target, enc);
570571
}
571572

573+
/**
574+
* Factory method for constructing {@link JsonGenerator} that is properly
575+
* wired to allow callbacks for serialization: basically
576+
* constructs a {@link ObjectWriteContext} and then calls
577+
* {@link TokenStreamFactory#createGenerator(ObjectWriteContext,Path,JsonEncoding)}.
578+
*
579+
* @since 3.0
580+
*/
581+
public JsonGenerator createGenerator(Path target, JsonEncoding enc) {
582+
_assertNotNull("target", target);
583+
return _generatorFactory.createGenerator(_serializerProvider(), target, enc);
584+
}
585+
572586
/**
573587
* Factory method for constructing {@link JsonGenerator} that is properly
574588
* wired to allow callbacks for serialization: basically
@@ -622,6 +636,28 @@ public SequenceWriter writeValues(File target)
622636
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), true);
623637
}
624638

639+
/**
640+
* Method for creating a {@link SequenceWriter} to write a sequence of root
641+
* values using configuration of this {@link ObjectWriter}.
642+
* Sequence is not surrounded by JSON array; some backend types may not
643+
* support writing of such sequences as root level.
644+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
645+
* values have been written to ensure closing of underlying generator and
646+
* output stream.
647+
*
648+
* @param target Target path to write value sequence to.
649+
*
650+
* @since 3.0
651+
*/
652+
public SequenceWriter writeValues(Path target)
653+
throws JacksonException
654+
{
655+
_assertNotNull("target", target);
656+
SerializationContextExt ctxt = _serializerProvider();
657+
return _newSequenceWriter(ctxt, false,
658+
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), true);
659+
}
660+
625661
/**
626662
* Method for creating a {@link SequenceWriter} to write a sequence of root
627663
* values using configuration of this {@link ObjectWriter}.
@@ -707,6 +743,30 @@ public SequenceWriter writeValuesAsArray(File target)
707743
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), true);
708744
}
709745

746+
/**
747+
* Method for creating a {@link SequenceWriter} to write an array of
748+
* root-level values, using configuration of this {@link ObjectWriter}.
749+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
750+
* values have been written to ensure closing of underlying generator and
751+
* output stream.
752+
*<p>
753+
* Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
754+
* be type of individual values (elements) to write and NOT matching array
755+
* or {@link java.util.Collection} type.
756+
*
757+
* @param target Path to write token stream to
758+
*
759+
* @since 3.0
760+
*/
761+
public SequenceWriter writeValuesAsArray(Path target)
762+
throws JacksonException
763+
{
764+
_assertNotNull("target", target);
765+
SerializationContextExt ctxt = _serializerProvider();
766+
return _newSequenceWriter(ctxt, true,
767+
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), true);
768+
}
769+
710770
/**
711771
* Method for creating a {@link SequenceWriter} to write an array of
712772
* root-level values, using configuration of this {@link ObjectWriter}.
@@ -891,6 +951,21 @@ public void writeValue(File target, Object value)
891951
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), value);
892952
}
893953

954+
/**
955+
* Method that can be used to serialize any Java value as
956+
* JSON output, written to Path provided.
957+
*
958+
* @since 3.0
959+
*/
960+
public void writeValue(Path target, Object value)
961+
throws JacksonException
962+
{
963+
_assertNotNull("target", target);
964+
SerializationContextExt ctxt = _serializerProvider();
965+
_configAndWriteValue(ctxt,
966+
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), value);
967+
}
968+
894969
/**
895970
* Method that can be used to serialize any Java value as
896971
* JSON output, using output stream provided (using encoding

0 commit comments

Comments
 (0)