Introduce Settings container in AbstractAotProcessor

See gh-29266
This commit is contained in:
Sam Brannen 2022-10-10 18:41:42 +02:00
parent 7b4ff5ea74
commit cad7444afa
5 changed files with 159 additions and 94 deletions

View File

@ -23,6 +23,7 @@ import org.springframework.aot.generate.FileSystemGeneratedFiles;
import org.springframework.aot.generate.GeneratedFiles.Kind; import org.springframework.aot.generate.GeneratedFiles.Kind;
import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.nativex.FileNativeConfigurationWriter; import org.springframework.aot.nativex.FileNativeConfigurationWriter;
import org.springframework.lang.Nullable;
import org.springframework.util.FileSystemUtils; import org.springframework.util.FileSystemUtils;
/** /**
@ -43,77 +44,30 @@ import org.springframework.util.FileSystemUtils;
*/ */
public abstract class AbstractAotProcessor { public abstract class AbstractAotProcessor {
private final Path sourceOutput; private final Settings settings;
private final Path resourceOutput;
private final Path classOutput;
private final String groupId;
private final String artifactId;
/** /**
* Create a new processor instance. * Create a new processor instance with the supplied {@linkplain Settings settings}.
* @param sourceOutput the location of generated sources
* @param resourceOutput the location of generated resources
* @param classOutput the location of generated classes
* @param groupId the group ID of the application, used to locate
* {@code native-image.properties}
* @param artifactId the artifact ID of the application, used to locate
* {@code native-image.properties}
*/ */
protected AbstractAotProcessor(Path sourceOutput, Path resourceOutput, protected AbstractAotProcessor(Settings settings) {
Path classOutput, String groupId, String artifactId) { this.settings = settings;
this.sourceOutput = sourceOutput;
this.resourceOutput = resourceOutput;
this.classOutput = classOutput;
this.groupId = groupId;
this.artifactId = artifactId;
} }
/**
* Get the output directory for generated sources.
*/
protected Path getSourceOutput() {
return this.sourceOutput;
}
/** /**
* Get the output directory for generated resources. * Get the {@linkplain Settings settings} for this AOT processor.
*/ */
protected Path getResourceOutput() { protected Settings getSettings() {
return this.resourceOutput; return this.settings;
}
/**
* Get the output directory for generated classes.
*/
protected Path getClassOutput() {
return this.classOutput;
}
/**
* Get the group ID of the application.
*/
protected String getGroupId() {
return this.groupId;
}
/**
* Get the artifact ID of the application.
*/
protected String getArtifactId() {
return this.artifactId;
} }
/** /**
* Delete the source, resource, and class output directories. * Delete the source, resource, and class output directories.
*/ */
protected void deleteExistingOutput() { protected void deleteExistingOutput() {
deleteExistingOutput(getSourceOutput(), getResourceOutput(), getClassOutput()); deleteExistingOutput(getSettings().getSourceOutput(),
getSettings().getResourceOutput(), getSettings().getClassOutput());
} }
private void deleteExistingOutput(Path... paths) { private void deleteExistingOutput(Path... paths) {
@ -133,16 +87,121 @@ public abstract class AbstractAotProcessor {
private Path getRoot(Kind kind) { private Path getRoot(Kind kind) {
return switch (kind) { return switch (kind) {
case SOURCE -> getSourceOutput(); case SOURCE -> getSettings().getSourceOutput();
case RESOURCE -> getResourceOutput(); case RESOURCE -> getSettings().getResourceOutput();
case CLASS -> getClassOutput(); case CLASS -> getSettings().getClassOutput();
}; };
} }
protected void writeHints(RuntimeHints hints) { protected void writeHints(RuntimeHints hints) {
FileNativeConfigurationWriter writer = FileNativeConfigurationWriter writer = new FileNativeConfigurationWriter(
new FileNativeConfigurationWriter(getResourceOutput(), getGroupId(), getArtifactId()); getSettings().getResourceOutput(), getSettings().getGroupId(), getSettings().getArtifactId());
writer.write(hints); writer.write(hints);
} }
/**
* Common settings for AOT processors.
*/
public static class Settings {
@Nullable
private Path sourceOutput;
@Nullable
private Path resourceOutput;
@Nullable
private Path classOutput;
@Nullable
private String groupId;
@Nullable
private String artifactId;
/**
* Set the output directory for generated sources.
* @param sourceOutput the location of generated sources
*/
public void setSourceOutput(Path sourceOutput) {
this.sourceOutput = sourceOutput;
}
/**
* Get the output directory for generated sources.
*/
@Nullable
public Path getSourceOutput() {
return this.sourceOutput;
}
/**
* Set the output directory for generated resources.
* @param resourceOutput the location of generated resources
*/
public void setResourceOutput(Path resourceOutput) {
this.resourceOutput = resourceOutput;
}
/**
* Get the output directory for generated resources.
*/
@Nullable
public Path getResourceOutput() {
return this.resourceOutput;
}
/**
* Set the output directory for generated classes.
* @param classOutput the location of generated classes
*/
public void setClassOutput(Path classOutput) {
this.classOutput = classOutput;
}
/**
* Get the output directory for generated classes.
*/
@Nullable
public Path getClassOutput() {
return this.classOutput;
}
/**
* Set the group ID of the application.
* @param groupId the group ID of the application, used to locate
* {@code native-image.properties}
*/
public void setGroupId(String groupId) {
this.groupId = groupId;
}
/**
* Get the group ID of the application.
*/
@Nullable
public String getGroupId() {
return this.groupId;
}
/**
* Set the artifact ID of the application.
* @param artifactId the artifact ID of the application, used to locate
* {@code native-image.properties}
*/
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
/**
* Get the artifact ID of the application.
*/
@Nullable
public String getArtifactId() {
return this.artifactId;
}
}
} }

View File

@ -50,20 +50,13 @@ public abstract class ContextAotProcessor extends AbstractAotProcessor {
private final Class<?> application; private final Class<?> application;
/** /**
* Create a new processor instance. * Create a new processor for the specified application entry point and
* common settings.
* @param application the application entry point * @param application the application entry point
* @param sourceOutput the location of generated sources * @param settings the settings to apply
* @param resourceOutput the location of generated resources
* @param classOutput the location of generated classes
* @param groupId the group ID of the application, used to locate
* {@code native-image.properties}
* @param artifactId the artifact ID of the application, used to locate
* {@code native-image.properties}
*/ */
protected ContextAotProcessor(Class<?> application, Path sourceOutput, Path resourceOutput, protected ContextAotProcessor(Class<?> application, Settings settings) {
Path classOutput, String groupId, String artifactId) { super(settings);
super(sourceOutput, resourceOutput, classOutput, groupId, artifactId);
this.application = application; this.application = application;
} }
@ -160,8 +153,8 @@ public abstract class ContextAotProcessor extends AbstractAotProcessor {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Args = "); sb.append("Args = ");
sb.append(String.join(String.format(" \\%n"), args)); sb.append(String.join(String.format(" \\%n"), args));
Path file = getResourceOutput() Path file = getSettings().getResourceOutput().resolve("META-INF/native-image/" +
.resolve("META-INF/native-image/" + getGroupId() + "/" + getArtifactId() + "/native-image.properties"); getSettings().getGroupId() + "/" + getSettings().getArtifactId() + "/native-image.properties");
try { try {
if (!Files.exists(file)) { if (!Files.exists(file)) {
Files.createDirectories(file.getParent()); Files.createDirectories(file.getParent());

View File

@ -118,14 +118,23 @@ class ContextAotProcessorTests {
private static class DemoContextAotProcessor extends ContextAotProcessor { private static class DemoContextAotProcessor extends ContextAotProcessor {
DemoContextAotProcessor(Class<?> application, DemoContextAotProcessor(Class<?> application, Path rootPath) {
Path sourceOutput, Path resourceOutput, Path classOutput) { this(application, rootPath.resolve("source"), rootPath.resolve("resource"), rootPath.resolve("class"));
super(application, sourceOutput, resourceOutput, classOutput, "com.example", "example");
} }
DemoContextAotProcessor(Class<?> application, Path rootPath) { DemoContextAotProcessor(Class<?> application, Path sourceOutput, Path resourceOutput, Path classOutput) {
super(application, rootPath.resolve("source"), rootPath.resolve("resource"), super(application, createSettings(sourceOutput, resourceOutput, classOutput, "com.example", "example"));
rootPath.resolve("class"), "com.example", "example"); }
private static Settings createSettings(Path sourceOutput, Path resourceOutput,
Path classOutput, String groupId, String artifactId) {
Settings settings = new Settings();
settings.setSourceOutput(sourceOutput);
settings.setResourceOutput(resourceOutput);
settings.setClassOutput(classOutput);
settings.setArtifactId(artifactId);
settings.setGroupId(groupId);
return settings;
} }
@Override @Override

View File

@ -43,20 +43,12 @@ public abstract class TestAotProcessor extends AbstractAotProcessor {
/** /**
* Create a new processor for the specified test classpath roots and * Create a new processor for the specified test classpath roots and
* general settings. * common settings.
* @param classpathRoots the classpath roots to scan for test classes * @param classpathRoots the classpath roots to scan for test classes
* @param sourceOutput the location of generated sources * @param settings the settings to apply
* @param resourceOutput the location of generated resources
* @param classOutput the location of generated classes
* @param groupId the group ID of the application, used to locate
* {@code native-image.properties}
* @param artifactId the artifact ID of the application, used to locate
* {@code native-image.properties}
*/ */
public TestAotProcessor(Set<Path> classpathRoots, Path sourceOutput, Path resourceOutput, Path classOutput, protected TestAotProcessor(Set<Path> classpathRoots, Settings settings) {
String groupId, String artifactId) { super(settings);
super(sourceOutput, resourceOutput, classOutput, groupId, artifactId);
this.classpathRoots = classpathRoots; this.classpathRoots = classpathRoots;
} }

View File

@ -104,8 +104,20 @@ class TestAotProcessorTests extends AbstractAotTests {
DemoTestAotProcessor(Set<Path> classpathRoots, Path sourceOutput, Path resourceOutput, Path classOutput, DemoTestAotProcessor(Set<Path> classpathRoots, Path sourceOutput, Path resourceOutput, Path classOutput,
String groupId, String artifactId) { String groupId, String artifactId) {
super(classpathRoots, sourceOutput, resourceOutput, classOutput, groupId, artifactId); super(classpathRoots, createSettings(sourceOutput, resourceOutput, classOutput, groupId, artifactId));
} }
private static Settings createSettings(Path sourceOutput, Path resourceOutput, Path classOutput, String groupId,
String artifactId) {
Settings settings = new Settings();
settings.setSourceOutput(sourceOutput);
settings.setResourceOutput(resourceOutput);
settings.setClassOutput(classOutput);
settings.setArtifactId(artifactId);
settings.setGroupId(groupId);
return settings;
}
} }
} }