Provide more control over registration of GeneratedFiles

This commit provides an advanced handling of generated files that
provides more control over files registration. The callback provides
a FileHandler that can determine if the file already exists and its
content. The caller can then chose to override the content or leave it
as it is.

Closes gh-31331
This commit is contained in:
Stephane Nicoll
2024-06-22 17:55:36 +02:00
committed by Stéphane Nicoll
parent e6b77d301d
commit 2650da2b53
6 changed files with 236 additions and 40 deletions

View File

@@ -23,16 +23,20 @@ import java.util.function.Function;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.aot.generate.GeneratedFiles.FileHandler;
import org.springframework.aot.generate.GeneratedFiles.Kind;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.util.function.ThrowingConsumer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link FileSystemGeneratedFiles}.
*
* @author Phillip Webb
* @author Stephane Nicoll
*/
class FileSystemGeneratedFilesTests {
@@ -82,7 +86,7 @@ class FileSystemGeneratedFilesTests {
void createWhenRootsResultsInNullThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new FileSystemGeneratedFiles(kind -> (kind != Kind.CLASS) ?
this.root.resolve(kind.toString()) : null))
this.root.resolve(kind.toString()) : null))
.withMessage("'roots' must return a value for all file kinds");
}
@@ -94,6 +98,46 @@ class FileSystemGeneratedFilesTests {
assertPathMustBeRelative(generatedFiles, "test/../../test");
}
@Test
void addFileWhenFileAlreadyAddedThrowsException() {
FileSystemGeneratedFiles generatedFiles = new FileSystemGeneratedFiles(this.root);
generatedFiles.addResourceFile("META-INF/test", "test");
assertThatIllegalStateException().isThrownBy(
() -> generatedFiles.addResourceFile("META-INF/test", "test"))
.withMessageContaining("META-INF/test", "already exists");
}
@Test
void handleFileWhenFileExistsProvidesFileHandler() {
FileSystemGeneratedFiles generatedFiles = new FileSystemGeneratedFiles(this.root);
generatedFiles.addResourceFile("META-INF/test", "test");
generatedFiles.handleFile(Kind.RESOURCE, "META-INF/test", handler -> {
assertThat(handler.exists()).isTrue();
assertThat(handler.getContent()).isNotNull();
assertThat(handler.getContent().getInputStream()).hasContent("test");
});
assertThat(this.root.resolve("resources/META-INF/test")).content().isEqualTo("test");
}
@Test
void handleFileWhenFileExistsFailsToCreate() {
FileSystemGeneratedFiles generatedFiles = new FileSystemGeneratedFiles(this.root);
generatedFiles.addResourceFile("META-INF/test", "test");
ThrowingConsumer<FileHandler> consumer = handler -> handler.create(new ByteArrayResource("should fail".getBytes(StandardCharsets.UTF_8)));
assertThatIllegalStateException()
.isThrownBy(() -> generatedFiles.handleFile(Kind.RESOURCE, "META-INF/test", consumer))
.withMessageContaining("META-INF/test", "already exists");
}
@Test
void handleFileWhenFileExistsCanOverrideContent() {
FileSystemGeneratedFiles generatedFiles = new FileSystemGeneratedFiles(this.root);
generatedFiles.addResourceFile("META-INF/test", "test");
generatedFiles.handleFile(Kind.RESOURCE, "META-INF/test", handler ->
handler.override(new ByteArrayResource("overridden".getBytes(StandardCharsets.UTF_8))));
assertThat(this.root.resolve("resources/META-INF/test")).content().isEqualTo("overridden");
}
private void assertPathMustBeRelative(FileSystemGeneratedFiles generatedFiles, String path) {
assertThatIllegalArgumentException()
.isThrownBy(() -> generatedFiles.addResourceFile(path, "test"))

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -32,6 +32,8 @@ import org.springframework.core.io.Resource;
import org.springframework.javapoet.JavaFile;
import org.springframework.javapoet.MethodSpec;
import org.springframework.javapoet.TypeSpec;
import org.springframework.lang.Nullable;
import org.springframework.util.function.ThrowingConsumer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -40,6 +42,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
* Tests for {@link GeneratedFiles}.
*
* @author Phillip Webb
* @author Stephane Nicoll
*/
class GeneratedFilesTests {
@@ -159,30 +162,45 @@ class GeneratedFilesTests {
return this.generatedFiles.assertThatFileAdded(kind, path);
}
static class TestGeneratedFiles implements GeneratedFiles {
static class TestGeneratedFiles extends GeneratedFiles {
private Kind kind;
private String path;
private InputStreamSource content;
private final TestFileHandler fileHandler = new TestFileHandler();
@Override
public void addFile(Kind kind, String path, InputStreamSource content) {
public void handleFile(Kind kind, String path, ThrowingConsumer<FileHandler> handler) {
this.kind = kind;
this.path = path;
this.content = content;
handler.accept(this.fileHandler);
}
AbstractStringAssert<?> assertThatFileAdded(Kind kind, String path)
throws IOException {
assertThat(this.kind).as("kind").isEqualTo(kind);
assertThat(this.path).as("path").isEqualTo(path);
assertThat(this.fileHandler.content).as("content").isNotNull();
ByteArrayOutputStream out = new ByteArrayOutputStream();
this.content.getInputStream().transferTo(out);
this.fileHandler.content.getInputStream().transferTo(out);
return assertThat(out.toString(StandardCharsets.UTF_8));
}
private static class TestFileHandler extends FileHandler {
@Nullable
private InputStreamSource content;
TestFileHandler() {
super(false, () -> null);
}
@Override
protected void copy(InputStreamSource content, boolean override) {
this.content = content;
}
}
}
}

View File

@@ -44,7 +44,7 @@ class InMemoryGeneratedFilesTests {
this.generatedFiles.addResourceFile("META-INF/test", "test");
assertThatIllegalStateException().isThrownBy(
() -> this.generatedFiles.addResourceFile("META-INF/test", "test"))
.withMessage("Path 'META-INF/test' already in use");
.withMessage("META-INF/test already exists");
}
@Test