Skip to content

Commit

Permalink
Create UrlResource factory methods that throw unchecked exceptions
Browse files Browse the repository at this point in the history
UrlResource constructors throw checked exceptions which makes it
difficult to use them in java.util.Stream and java.util.Optional APIs
or other scenarios when a checked IOException is undesirable.

To support such use cases, this commit introduces `from(URI)` and
`from(String)` factory methods in UrlResource that throw
UncheckedIOExceptions.

Closes spring-projectsgh-28501
  • Loading branch information
sbrannen committed May 23, 2022
1 parent 4515180 commit f07e7ab
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
Expand All @@ -37,6 +38,7 @@
* case of the {@code "file:"} protocol.
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 28.12.2003
* @see java.net.URL
*/
Expand Down Expand Up @@ -135,6 +137,49 @@ public UrlResource(String protocol, String location, @Nullable String fragment)
}


/**
* Create a new {@code UrlResource} from the given {@link URI}.
* <p>This factory method is a convenience for {@link #UrlResource(URI)} that
* catches any {@link MalformedURLException} and rethrows it wrapped in an
* {@link UncheckedIOException}; suitable for use in {@link java.util.Stream}
* and {@link java.util.Optional} APIs or other scenarios when a checked
* {@link IOException} is undesirable.
* @param uri a URI
* @throws UncheckedIOException if the given URL path is not valid
* @since 6.0
* @see #UrlResource(URI)
*/
public static UrlResource from(URI uri) throws UncheckedIOException {
try {
return new UrlResource(uri);
}
catch (MalformedURLException ex) {
throw new UncheckedIOException(ex);
}
}

/**
* Create a new {@code UrlResource} from the given URL path.
* <p>This factory method is a convenience for {@link #UrlResource(String)}
* that catches any {@link MalformedURLException} and rethrows it wrapped in an
* {@link UncheckedIOException}; suitable for use in {@link java.util.Stream}
* and {@link java.util.Optional} APIs or other scenarios when a checked
* {@link IOException} is undesirable.
* @param path a URL path
* @throws UncheckedIOException if the given URL path is not valid
* @since 6.0
* @see #UrlResource(String)
*/
public static UrlResource from(String path) throws UncheckedIOException {
try {
return new UrlResource(path);
}
catch (MalformedURLException ex) {
throw new UncheckedIOException(ex);
}
}


/**
* Determine a cleaned URL for the given original URL.
* @param originalUrl the original URL
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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 @@ -208,6 +208,21 @@ private void doTestResource(Resource resource) throws IOException {
relative4::lastModified);
}

@Test
void urlResourceFactoryMethods() throws IOException {
Resource resource1 = new UrlResource("file:core/io/Resource.class");
Resource resource2 = UrlResource.from("file:core/io/Resource.class");
Resource resource3 = UrlResource.from(resource1.getURI());

assertThat(resource2.getURL()).isEqualTo(resource1.getURL());
assertThat(resource3.getURL()).isEqualTo(resource1.getURL());

assertThat(UrlResource.from("file:core/../core/io/./Resource.class")).isEqualTo(resource1);
assertThat(UrlResource.from("file:/dir/test.txt?argh").getFilename()).isEqualTo("test.txt");
assertThat(UrlResource.from("file:\\dir\\test.txt?argh").getFilename()).isEqualTo("test.txt");
assertThat(UrlResource.from("file:\\dir/test.txt?argh").getFilename()).isEqualTo("test.txt");
}

@Test
void classPathResourceWithRelativePath() throws IOException {
Resource resource = new ClassPathResource("dir/");
Expand Down

0 comments on commit f07e7ab

Please sign in to comment.