Skip to content

Commit

Permalink
Polishing external contribution
Browse files Browse the repository at this point in the history
This commit makes several changes to PR spring-projects#24651.

- Add byte[] getContentAsByteArray() on Resource.
- Remove getContentAsString() from Resource, as it relied on the default
charset which is not reliable.
- Add getContentAsString() to EncodedResource, as a charset is provided
through the constructor.

See spring-projectsgh-24651
  • Loading branch information
poutsma committed Feb 14, 2023
1 parent 4da2499 commit 12d4dc1
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.jar.JarEntry;

Expand Down Expand Up @@ -323,39 +320,6 @@ protected void customizeConnection(URLConnection con) throws IOException {
protected void customizeConnection(HttpURLConnection con) throws IOException {
}

/**
* This implementation returns the contents of a file as a string using the
* system default Charset. Provided the resource exists and the context has
* access to it, the contents will be returned as a single string with line
* feed characters retained.
* @return the contents of the requested file as a {@code String}.
* @throws FileNotFoundException in the event the file path is invalid.
* @throws IOException if the file can not be read or cannot be serialzied.
*/
@Override
public String getContentAsString() throws IOException {

if( !exists() ) {
throw new FileNotFoundException(getDescription() + " cannot be found.");
}
if ( !isReadable() ) {
throw new IOException(getDescription() + " cannot be opened for reading.");
}
return new String(Files.readAllBytes(Paths.get(getFile().getAbsolutePath())), Charset.defaultCharset());
}

@Override
public String getContentAsString(Charset charset) throws IOException {

if( !exists() ) {
throw new FileNotFoundException(getDescription() + " cannot be found.");
}
if ( !isReadable() ) {
throw new IOException(getDescription() + " cannot be opened for reading.");
}
return new String(Files.readAllBytes(Paths.get(getFile().getAbsolutePath())), charset);

}

/**
* Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,6 +19,7 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Arrays;

import org.springframework.lang.Nullable;
Expand Down Expand Up @@ -100,6 +101,19 @@ public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(this.byteArray);
}

@Override
public byte[] getContentAsByteArray() throws IOException {
int length = this.byteArray.length;
byte[] result = new byte[length];
System.arraycopy(this.byteArray, 0, result, 0, length);
return result;
}

@Override
public String getContentAsString(Charset charset) throws IOException {
return new String(this.byteArray, charset);
}

/**
* This implementation returns a description that includes the passed-in
* {@code description}, if any.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,6 +27,7 @@
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
Expand Down Expand Up @@ -196,6 +197,26 @@ public InputStream getInputStream() throws IOException {
}
}

@Override
public byte[] getContentAsByteArray() throws IOException {
try {
return Files.readAllBytes(this.filePath);
}
catch (NoSuchFileException ex) {
throw new FileNotFoundException(ex.getMessage());
}
}

@Override
public String getContentAsString(Charset charset) throws IOException {
try {
return Files.readString(this.filePath, charset);
}
catch (NoSuchFileException ex) {
throw new FileNotFoundException(ex.getMessage());
}
}

/**
* This implementation checks whether the underlying file is marked as writable
* (and corresponds to an actual file with content, not to a directory).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@
import java.net.URL;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.OpenOption;
Expand Down Expand Up @@ -141,6 +142,26 @@ public InputStream getInputStream() throws IOException {
return Files.newInputStream(this.path);
}

@Override
public byte[] getContentAsByteArray() throws IOException {
try {
return Files.readAllBytes(this.path);
}
catch (NoSuchFileException ex) {
throw new FileNotFoundException(ex.getMessage());
}
}

@Override
public String getContentAsString(Charset charset) throws IOException {
try {
return Files.readString(this.path, charset);
}
catch (NoSuchFileException ex) {
throw new FileNotFoundException(ex.getMessage());
}
}

/**
* This implementation checks whether the underlying file is marked as writable
* (and corresponds to an actual file with content, not to a directory).
Expand Down
52 changes: 21 additions & 31 deletions spring-core/src/main/java/org/springframework/core/io/Resource.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,16 +17,17 @@
package org.springframework.core.io;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;

import org.springframework.lang.Nullable;
import org.springframework.util.FileCopyUtils;

/**
* Interface for a resource descriptor that abstracts from the actual
Expand Down Expand Up @@ -179,40 +180,29 @@ default ReadableByteChannel readableChannel() throws IOException {
String getDescription();

/**
* Return a {@link ReadableByteChannel}.
* <p>It is expected that each call creates a <i>fresh</i> channel.
* <p>The default implementation returns {@link Channels#newChannel(InputStream)}
* with the result of {@link #getInputStream()}.
* @return the byte channel for the underlying resource (must not be {@code null})
* @throws java.io.FileNotFoundException if the underlying resource doesn't exist
* @throws IOException if the content channel could not be opened
* @since 5.0
* @see #getInputStream()
*/

/**
* Returns the contents of a file as a string using the system default Charset.
* <p>The default implementation returns a {@link Object#toString()} representation of the resource.
* @return the contents of the requested file as a {@code String}.
* @throws FileNotFoundException in the event the file path is invalid.
* @throws IOException if the file can not be read or cannot be accessed.
* @since 5.2.5
* Return the contents of this resource as a byte array.
* @return the contents of this resource as byte array
* @throws java.io.FileNotFoundException if the resource cannot be resolved as
* absolute file path, i.e. if the resource is not available in a file system
* @throws IOException in case of general resolution/reading failures
* @since 6.0.5
*/
default String getContentAsString() throws IOException{
return toString();
default byte[] getContentAsByteArray() throws IOException {
return FileCopyUtils.copyToByteArray(getInputStream());
}

/**
* Returns the contents of a file as a string using the specified Charset.
* <p>The default implementation returns a {@link Object#toString()} representation of the resource.
* @param charset the {@code Charset} to use to deserialize the content. Defaults to system default.
* @return the contents of the requested file as a {@code String}.
* @throws FileNotFoundException in the event the file path is invalid.
* @throws IOException if the file can not be read or cannot be accessed.
* @since 5.2.5
* Returns the contents of this resource as a string, using the specified
* charset.
* @param charset the charset to use for decoding
* @return the contents of this resource as a {@code String}
* @throws java.io.FileNotFoundException if the resource cannot be resolved as
* absolute file path, i.e. if the resource is not available in a file system
* @throws IOException in case of general resolution/reading failures
* @since 6.0.5
*/
default String getContentAsString(Charset charset) throws IOException{
return toString();
default String getContentAsString(Charset charset) throws IOException {
return FileCopyUtils.copyToString(new InputStreamReader(getInputStream(), charset));
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -159,6 +159,27 @@ public InputStream getInputStream() throws IOException {
return this.resource.getInputStream();
}

/**
* Returns the contents of the specified resource as a string, using the specified
* {@link #getCharset() Charset} or {@linkplain #getEncoding() encoding}
* (if any).
* @throws IOException if opening the resource failed
* @since 6.0.5
*/
public String getContentAsString() throws IOException {
Charset charset;
if (this.charset != null) {
charset = this.charset;
}
else if (this.encoding != null) {
charset = Charset.forName(this.encoding);
}
else {
charset = Charset.defaultCharset();
}
return this.resource.getContentAsString(charset);
}


@Override
public boolean equals(@Nullable Object other) {
Expand Down
Loading

0 comments on commit 12d4dc1

Please sign in to comment.