Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2013: add support for reading from / writing to a Path #3066

Merged
merged 1 commit into from
Feb 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.*;
import java.lang.reflect.Type;
import java.net.URL;
import java.nio.file.Path;
import java.text.DateFormat;
import java.util.Collection;
import java.util.List;
Expand Down Expand Up @@ -583,6 +584,20 @@ public JsonParser createParser(File src) throws JacksonException {
return ctxt.assignAndReturnParser(_streamFactory.createParser(ctxt, src));
}

/**
* Factory method for constructing {@link JsonParser} that is properly
* wired to allow callbacks for deserialization: basically
* constructs a {@link ObjectReadContext} and then calls
* {@link TokenStreamFactory#createParser(ObjectReadContext,Path)}.
*
* @since 3.0
*/
public JsonParser createParser(Path src) throws JacksonException {
_assertNotNull("src", src);
DeserializationContextExt ctxt = _deserializationContext();
return ctxt.assignAndReturnParser(_streamFactory.createParser(ctxt, src));
}

/**
* Factory method for constructing {@link JsonParser} that is properly
* wired to allow callbacks for deserialization: basically
Expand Down Expand Up @@ -781,6 +796,19 @@ public JsonGenerator createGenerator(File f, JsonEncoding enc) throws JacksonExc
return _streamFactory.createGenerator(_serializerProvider(), f, enc);
}

/**
* Factory method for constructing {@link JsonGenerator} that is properly
* wired to allow callbacks for serialization: basically
* constructs a {@link ObjectWriteContext} and then calls
* {@link TokenStreamFactory#createGenerator(ObjectWriteContext,Path,JsonEncoding)}.
*
* @since 3.0
*/
public JsonGenerator createGenerator(Path p, JsonEncoding enc) throws JacksonException {
_assertNotNull("p", p);
return _streamFactory.createGenerator(_serializerProvider(), p, enc);
}

/**
* Factory method for constructing {@link JsonGenerator} that is properly
* wired to allow callbacks for serialization: basically
Expand Down Expand Up @@ -1151,6 +1179,19 @@ public JsonNode readTree(File file) throws JacksonException
return _readTreeAndClose(ctxt, _streamFactory.createParser(ctxt, file));
}

/**
* Same as {@link #readTree(InputStream)} except content read from
* passed-in {@link Path}.
*
* @since 3.0
*/
public JsonNode readTree(Path path) throws JacksonException
{
_assertNotNull("path", path);
DeserializationContextExt ctxt = _deserializationContext();
return _readTreeAndClose(ctxt, _streamFactory.createParser(ctxt, path));
}

/**
* Same as {@link #readTree(InputStream)} except content read from
* passed-in {@link URL}.
Expand Down Expand Up @@ -1365,6 +1406,74 @@ public <T> T readValue(File src, JavaType valueType) throws JacksonException
return (T) _readMapAndClose(ctxt, _streamFactory.createParser(ctxt, src), valueType);
}

/**
* Method to deserialize JSON content from given path into given Java type.
*
* @throws WrappedIOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws StreamReadException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws DatabindException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*
* @since 3.0
*/
@SuppressWarnings("unchecked")
public <T> T readValue(Path src, Class<T> valueType) throws JacksonException
{
_assertNotNull("src", src);
DeserializationContextExt ctxt = _deserializationContext();
return (T) _readMapAndClose(ctxt, _streamFactory.createParser(ctxt, src),
_typeFactory.constructType(valueType));
}

/**
* Method to deserialize JSON content from given path into given Java type.
*
* @throws WrappedIOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws StreamReadException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws DatabindException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*
* @since 3.0
*/
@SuppressWarnings({ "unchecked" })
public <T> T readValue(Path src, TypeReference<T> valueTypeRef) throws JacksonException
{
_assertNotNull("src", src);
DeserializationContextExt ctxt = _deserializationContext();
return (T) _readMapAndClose(ctxt, _streamFactory.createParser(ctxt, src),
_typeFactory.constructType(valueTypeRef));
}

/**
* Method to deserialize JSON content from given path into given Java type.
*
* @throws WrappedIOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws StreamReadException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws DatabindException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*
* @since 3.0
*/
@SuppressWarnings("unchecked")
public <T> T readValue(Path src, JavaType valueType) throws JacksonException
{
_assertNotNull("src", src);
DeserializationContextExt ctxt = _deserializationContext();
return (T) _readMapAndClose(ctxt, _streamFactory.createParser(ctxt, src), valueType);
}

/**
* Method to deserialize JSON content from given resource into given Java type.
*<p>
Expand Down Expand Up @@ -1610,6 +1719,15 @@ public <T> T readValue(DataInput src, JavaType valueType) throws JacksonExceptio
_streamFactory.createParser(ctxt, src), valueType);
}

@SuppressWarnings("unchecked")
public <T> T readValue(DataInput src, TypeReference<T> valueTypeRef) throws JacksonException
{
_assertNotNull("src", src);
DeserializationContextExt ctxt = _deserializationContext();
return (T) _readMapAndClose(ctxt,
_streamFactory.createParser(ctxt, src), _typeFactory.constructType(valueTypeRef));
}

/*
/**********************************************************************
/* Public API: serialization (mapping from Java types to external format)
Expand All @@ -1628,6 +1746,20 @@ public void writeValue(File file, Object value) throws JacksonException
_streamFactory.createGenerator(prov, file, JsonEncoding.UTF8), value);
}

/**
* Method that can be used to serialize any Java value as
* JSON output, written to Path provided.
*
* @since 3.0
*/
public void writeValue(Path path, Object value) throws JacksonException
{
_assertNotNull("path", path);
SerializationContextExt prov = _serializerProvider();
_configAndWriteValue(prov,
_streamFactory.createGenerator(prov, path, JsonEncoding.UTF8), value);
}

/**
* Method that can be used to serialize any Java value as
* JSON output, using output stream provided (using encoding
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/com/fasterxml/jackson/databind/ObjectReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

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

/**
* Factory method for constructing {@link JsonParser} that is properly
* wired to allow callbacks for deserialization: basically
* constructs a {@link ObjectReadContext} and then calls
* {@link TokenStreamFactory#createParser(ObjectReadContext,Path)}.
*
* @since 3.0
*/
public JsonParser createParser(Path src) throws JacksonException {
_assertNotNull("src", src);
DeserializationContextExt ctxt = _deserializationContext();
return ctxt.assignAndReturnParser(_parserFactory.createParser(ctxt, src));
}

/**
* Factory method for constructing {@link JsonParser} that is properly
* wired to allow callbacks for deserialization: basically
Expand Down Expand Up @@ -1202,6 +1218,25 @@ public <T> T readValue(File f) throws JacksonException
_considerFilter(_parserFactory.createParser(ctxt, f), false));
}

/**
* Method that binds content read from given {@link Path}
* using configuration of this reader.
* Value return is either newly constructed, or root value that
* was specified with {@link #withValueToUpdate(Object)}.
*
* @param p Path that contains content to read
*
* @since 3.0
*/
@SuppressWarnings("unchecked")
public <T> T readValue(Path p) throws JacksonException
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will change p to path just because p traditionally refers to JsonParser (or whatever it'll get renamed as)

{
_assertNotNull("p", p);
DeserializationContextExt ctxt = _deserializationContext();
return (T) _bindAndClose(ctxt,
_considerFilter(_parserFactory.createParser(ctxt, p), false));
}

/**
* Method that binds content read from given input source,
* using configuration of this reader.
Expand Down Expand Up @@ -1456,6 +1491,19 @@ public <T> MappingIterator<T> readValues(File src) throws JacksonException
_considerFilter(_parserFactory.createParser(ctxt, src), true));
}

/**
* Overloaded version of {@link #readValues(InputStream)}.
*
* @since 3.0
*/
public <T> MappingIterator<T> readValues(Path src) throws JacksonException
{
_assertNotNull("src", src);
DeserializationContextExt ctxt = _deserializationContext();
return _bindAndReadValues(ctxt,
_considerFilter(_parserFactory.createParser(ctxt, src), true));
}

/**
* Overloaded version of {@link #readValue(InputStream)}.
*<p>
Expand Down Expand Up @@ -1701,6 +1749,14 @@ protected InputStream _inputStream(File f) throws JacksonException {
}
}

protected InputStream _inputStream(Path p) throws JacksonException {
try {
return Files.newInputStream(p);
} catch (IOException e) {
throw WrappedIOException.construct(e);
}
}

protected final void _assertNotNull(String paramName, Object src) {
if (src == null){
throw new IllegalArgumentException(String.format("argument \"%s\" is null", paramName));
Expand Down
75 changes: 75 additions & 0 deletions src/main/java/com/fasterxml/jackson/databind/ObjectWriter.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.fasterxml.jackson.databind;

import java.io.*;
import java.nio.file.Path;
import java.text.*;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -569,6 +570,19 @@ public JsonGenerator createGenerator(File target, JsonEncoding enc) {
return _generatorFactory.createGenerator(_serializerProvider(), target, enc);
}

/**
* Factory method for constructing {@link JsonGenerator} that is properly
* wired to allow callbacks for serialization: basically
* constructs a {@link ObjectWriteContext} and then calls
* {@link TokenStreamFactory#createGenerator(ObjectWriteContext,Path,JsonEncoding)}.
*
* @since 3.0
*/
public JsonGenerator createGenerator(Path target, JsonEncoding enc) {
_assertNotNull("target", target);
return _generatorFactory.createGenerator(_serializerProvider(), target, enc);
}

/**
* Factory method for constructing {@link JsonGenerator} that is properly
* wired to allow callbacks for serialization: basically
Expand Down Expand Up @@ -622,6 +636,28 @@ public SequenceWriter writeValues(File target)
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), true);
}

/**
* Method for creating a {@link SequenceWriter} to write a sequence of root
* values using configuration of this {@link ObjectWriter}.
* Sequence is not surrounded by JSON array; some backend types may not
* support writing of such sequences as root level.
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
* values have been written to ensure closing of underlying generator and
* output stream.
*
* @param target Target path to write value sequence to.
*
* @since 3.0
*/
public SequenceWriter writeValues(Path target)
throws JacksonException
{
_assertNotNull("target", target);
SerializationContextExt ctxt = _serializerProvider();
return _newSequenceWriter(ctxt, false,
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), true);
}

/**
* Method for creating a {@link SequenceWriter} to write a sequence of root
* values using configuration of this {@link ObjectWriter}.
Expand Down Expand Up @@ -707,6 +743,30 @@ public SequenceWriter writeValuesAsArray(File target)
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), true);
}

/**
* Method for creating a {@link SequenceWriter} to write an array of
* root-level values, using configuration of this {@link ObjectWriter}.
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
* values have been written to ensure closing of underlying generator and
* output stream.
*<p>
* Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
* be type of individual values (elements) to write and NOT matching array
* or {@link java.util.Collection} type.
*
* @param target Path to write token stream to
*
* @since 3.0
*/
public SequenceWriter writeValuesAsArray(Path target)
throws JacksonException
{
_assertNotNull("target", target);
SerializationContextExt ctxt = _serializerProvider();
return _newSequenceWriter(ctxt, true,
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), true);
}

/**
* Method for creating a {@link SequenceWriter} to write an array of
* root-level values, using configuration of this {@link ObjectWriter}.
Expand Down Expand Up @@ -891,6 +951,21 @@ public void writeValue(File target, Object value)
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), value);
}

/**
* Method that can be used to serialize any Java value as
* JSON output, written to Path provided.
*
* @since 3.0
*/
public void writeValue(Path target, Object value)
throws JacksonException
{
_assertNotNull("target", target);
SerializationContextExt ctxt = _serializerProvider();
_configAndWriteValue(ctxt,
_generatorFactory.createGenerator(ctxt, target, JsonEncoding.UTF8), value);
}

/**
* Method that can be used to serialize any Java value as
* JSON output, using output stream provided (using encoding
Expand Down
Loading