Change `NestedLocation` to hold a `Path` rather than a `File`

Refactor `NestedLocation` so that it holds a `Path` rather than a
`File`.

See gh-37668
This commit is contained in:
Phillip Webb 2023-10-18 15:00:50 -07:00
parent ec6415f04b
commit 4b495ca2a9
5 changed files with 28 additions and 18 deletions

View File

@ -82,7 +82,7 @@ class UrlJarFileFactory {
private JarFile createJarFileForNested(URL url, Runtime.Version version, Consumer<JarFile> closeAction)
throws IOException {
NestedLocation location = NestedLocation.fromUrl(url);
return new UrlNestedJarFile(location.file(), location.nestedEntryName(), version, closeAction);
return new UrlNestedJarFile(location.path().toFile(), location.nestedEntryName(), version, closeAction);
}
private JarFile createJarFileForStream(URL url, Version version, Consumer<JarFile> closeAction) throws IOException {

View File

@ -16,8 +16,9 @@
package org.springframework.boot.loader.net.protocol.nested;
import java.io.File;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -43,18 +44,18 @@ import org.springframework.boot.loader.net.util.UrlDecoder;
* uncompressed entry that contains the nested jar, or a directory entry. The entry must
* not start with a {@code '/'}.
*
* @param file the zip file that contains the nested entry
* @param path the path to the zip that contains the nested entry
* @param nestedEntryName the nested entry name
* @author Phillip Webb
* @since 3.2.0
*/
public record NestedLocation(File file, String nestedEntryName) {
public record NestedLocation(Path path, String nestedEntryName) {
private static final Map<String, NestedLocation> cache = new ConcurrentHashMap<>();
public NestedLocation {
if (file == null) {
throw new IllegalArgumentException("'file' must not be null");
if (path == null) {
throw new IllegalArgumentException("'path' must not be null");
}
if (nestedEntryName == null || nestedEntryName.trim().isEmpty()) {
throw new IllegalArgumentException("'nestedEntryName' must not be empty");
@ -86,9 +87,9 @@ public record NestedLocation(File file, String nestedEntryName) {
}
private static NestedLocation create(int index, String location) {
String file = location.substring(0, index);
String path = location.substring(0, index);
String nestedEntryName = location.substring(index + 2);
return new NestedLocation((!file.isEmpty()) ? new File(file) : null, nestedEntryName);
return new NestedLocation((!path.isEmpty()) ? Path.of(path) : null, nestedEntryName);
}
static void clearCache() {

View File

@ -16,6 +16,7 @@
package org.springframework.boot.loader.net.protocol.nested;
import java.io.File;
import java.io.FilePermission;
import java.io.FilterInputStream;
import java.io.IOException;
@ -25,6 +26,7 @@ import java.lang.ref.Cleaner.Cleanable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.security.Permission;
import org.springframework.boot.loader.ref.Cleaner;
@ -43,7 +45,7 @@ class NestedUrlConnection extends URLConnection {
private final Cleanable cleanup;
private long lastModified;
private long lastModified = -1;
private FilePermission permission;
@ -91,8 +93,13 @@ class NestedUrlConnection extends URLConnection {
@Override
public long getLastModified() {
if (this.lastModified == 0) {
this.lastModified = this.resources.getLocation().file().lastModified();
if (this.lastModified == -1) {
try {
this.lastModified = Files.getLastModifiedTime(this.resources.getLocation().path()).toMillis();
}
catch (IOException ex) {
this.lastModified = 0;
}
}
return this.lastModified;
}
@ -100,7 +107,8 @@ class NestedUrlConnection extends URLConnection {
@Override
public Permission getPermission() throws IOException {
if (this.permission == null) {
this.permission = new FilePermission(this.resources.getLocation().file().getCanonicalPath(), "read");
File file = this.resources.getLocation().path().toFile();
this.permission = new FilePermission(file.getCanonicalPath(), "read");
}
return this.permission;
}

View File

@ -51,7 +51,7 @@ class NestedUrlConnectionResources implements Runnable {
void connect() throws IOException {
synchronized (this) {
if (this.zipContent == null) {
this.zipContent = ZipContent.open(this.location.file().toPath(), this.location.nestedEntryName());
this.zipContent = ZipContent.open(this.location.path(), this.location.nestedEntryName());
try {
connectData();
}

View File

@ -18,6 +18,7 @@ package org.springframework.boot.loader.net.protocol.nested;
import java.io.File;
import java.net.URL;
import java.nio.file.Path;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@ -44,20 +45,20 @@ class NestedLocationTests {
}
@Test
void createWhenFileIsNullThrowsException() {
void createWhenPathIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> new NestedLocation(null, "nested.jar"))
.withMessageContaining("'file' must not be null");
.withMessageContaining("'path' must not be null");
}
@Test
void createWhenNestedEntryNameIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> new NestedLocation(new File("test.jar"), null))
assertThatIllegalArgumentException().isThrownBy(() -> new NestedLocation(Path.of("test.jar"), null))
.withMessageContaining("'nestedEntryName' must not be empty");
}
@Test
void createWhenNestedEntryNameIsEmptyThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> new NestedLocation(new File("test.jar"), null))
assertThatIllegalArgumentException().isThrownBy(() -> new NestedLocation(Path.of("test.jar"), null))
.withMessageContaining("'nestedEntryName' must not be empty");
}
@ -91,7 +92,7 @@ class NestedLocationTests {
File file = new File(this.temp, "test.jar");
NestedLocation location = NestedLocation
.fromUrl(new URL("nested:" + file.getAbsolutePath() + "/!lib/nested.jar"));
assertThat(location.file()).isEqualTo(file);
assertThat(location.path()).isEqualTo(file.toPath());
assertThat(location.nestedEntryName()).isEqualTo("lib/nested.jar");
}