@ -1,5 +1,5 @@
@@ -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 .
@ -16,8 +16,11 @@
@@ -16,8 +16,11 @@
package org.springframework.aot.generate ;
import java.util.function.Supplier ;
import org.springframework.core.io.InputStreamSource ;
import org.springframework.javapoet.JavaFile ;
import org.springframework.lang.Nullable ;
import org.springframework.util.Assert ;
import org.springframework.util.ClassUtils ;
import org.springframework.util.StringUtils ;
@ -36,14 +39,14 @@ import org.springframework.util.function.ThrowingConsumer;
@@ -36,14 +39,14 @@ import org.springframework.util.function.ThrowingConsumer;
* @see InMemoryGeneratedFiles
* @see FileSystemGeneratedFiles
* /
public interface GeneratedFiles {
public abstract class GeneratedFiles {
/ * *
* Add a generated { @link Kind # SOURCE source file } with content from the
* given { @link JavaFile } .
* @param javaFile the java file to add
* /
default void addSourceFile ( JavaFile javaFile ) {
public void addSourceFile ( JavaFile javaFile ) {
validatePackage ( javaFile . packageName , javaFile . typeSpec . name ) ;
String className = javaFile . packageName + "." + javaFile . typeSpec . name ;
addSourceFile ( className , javaFile : : writeTo ) ;
@ -56,7 +59,7 @@ public interface GeneratedFiles {
@@ -56,7 +59,7 @@ public interface GeneratedFiles {
* of the file
* @param content the contents of the file
* /
default void addSourceFile ( String className , CharSequence content ) {
public void addSourceFile ( String className , CharSequence content ) {
addSourceFile ( className , appendable - > appendable . append ( content ) ) ;
}
@ -68,7 +71,7 @@ public interface GeneratedFiles {
@@ -68,7 +71,7 @@ public interface GeneratedFiles {
* @param content a { @link ThrowingConsumer } that accepts an
* { @link Appendable } which will receive the file contents
* /
default void addSourceFile ( String className , ThrowingConsumer < Appendable > content ) {
public void addSourceFile ( String className , ThrowingConsumer < Appendable > content ) {
addFile ( Kind . SOURCE , getClassNamePath ( className ) , content ) ;
}
@ -80,7 +83,7 @@ public interface GeneratedFiles {
@@ -80,7 +83,7 @@ public interface GeneratedFiles {
* @param content an { @link InputStreamSource } that will provide an input
* stream containing the file contents
* /
default void addSourceFile ( String className , InputStreamSource content ) {
public void addSourceFile ( String className , InputStreamSource content ) {
addFile ( Kind . SOURCE , getClassNamePath ( className ) , content ) ;
}
@ -90,7 +93,7 @@ public interface GeneratedFiles {
@@ -90,7 +93,7 @@ public interface GeneratedFiles {
* @param path the relative path of the file
* @param content the contents of the file
* /
default void addResourceFile ( String path , CharSequence content ) {
public void addResourceFile ( String path , CharSequence content ) {
addResourceFile ( path , appendable - > appendable . append ( content ) ) ;
}
@ -101,7 +104,7 @@ public interface GeneratedFiles {
@@ -101,7 +104,7 @@ public interface GeneratedFiles {
* @param content a { @link ThrowingConsumer } that accepts an
* { @link Appendable } which will receive the file contents
* /
default void addResourceFile ( String path , ThrowingConsumer < Appendable > content ) {
public void addResourceFile ( String path , ThrowingConsumer < Appendable > content ) {
addFile ( Kind . RESOURCE , path , content ) ;
}
@ -112,7 +115,7 @@ public interface GeneratedFiles {
@@ -112,7 +115,7 @@ public interface GeneratedFiles {
* @param content an { @link InputStreamSource } that will provide an input
* stream containing the file contents
* /
default void addResourceFile ( String path , InputStreamSource content ) {
public void addResourceFile ( String path , InputStreamSource content ) {
addFile ( Kind . RESOURCE , path , content ) ;
}
@ -123,7 +126,7 @@ public interface GeneratedFiles {
@@ -123,7 +126,7 @@ public interface GeneratedFiles {
* @param content an { @link InputStreamSource } that will provide an input
* stream containing the file contents
* /
default void addClassFile ( String path , InputStreamSource content ) {
public void addClassFile ( String path , InputStreamSource content ) {
addFile ( Kind . CLASS , path , content ) ;
}
@ -134,7 +137,7 @@ public interface GeneratedFiles {
@@ -134,7 +137,7 @@ public interface GeneratedFiles {
* @param path the relative path of the file
* @param content the contents of the file
* /
default void addFile ( Kind kind , String path , CharSequence content ) {
public void addFile ( Kind kind , String path , CharSequence content ) {
addFile ( kind , path , appendable - > appendable . append ( content ) ) ;
}
@ -146,7 +149,7 @@ public interface GeneratedFiles {
@@ -146,7 +149,7 @@ public interface GeneratedFiles {
* @param content a { @link ThrowingConsumer } that accepts an
* { @link Appendable } which will receive the file contents
* /
default void addFile ( Kind kind , String path , ThrowingConsumer < Appendable > content ) {
public void addFile ( Kind kind , String path , ThrowingConsumer < Appendable > content ) {
Assert . notNull ( content , "'content' must not be null" ) ;
addFile ( kind , path , new AppendableConsumerInputStreamSource ( content ) ) ;
}
@ -159,7 +162,21 @@ public interface GeneratedFiles {
@@ -159,7 +162,21 @@ public interface GeneratedFiles {
* @param content an { @link InputStreamSource } that will provide an input
* stream containing the file contents
* /
void addFile ( Kind kind , String path , InputStreamSource content ) ;
public void addFile ( Kind kind , String path , InputStreamSource content ) {
Assert . notNull ( kind , "'kind' must not be null" ) ;
Assert . hasLength ( path , "'path' must not be empty" ) ;
Assert . notNull ( content , "'content' must not be null" ) ;
handleFile ( kind , path , handler - > handler . create ( content ) ) ;
}
/ * *
* Add a generated file of the specified { @link Kind } with the given
* { @linkplain FileHandler handler } .
* @param kind the kind of file being written
* @param path the relative path of the file
* @param handler a consumer of a { @link FileHandler } for the file
* /
public abstract void handleFile ( Kind kind , String path , ThrowingConsumer < FileHandler > handler ) ;
private static String getClassNamePath ( String className ) {
Assert . hasLength ( className , "'className' must not be empty" ) ;
@ -194,7 +211,7 @@ public interface GeneratedFiles {
@@ -194,7 +211,7 @@ public interface GeneratedFiles {
/ * *
* The various kinds of generated files that are supported .
* /
enum Kind {
public enum Kind {
/ * *
* A source file containing Java code that should be compiled .
@ -215,4 +232,62 @@ public interface GeneratedFiles {
@@ -215,4 +232,62 @@ public interface GeneratedFiles {
}
/ * *
* Provide access to a particular file and offer convenient method to save
* or override its content .
* /
public abstract static class FileHandler {
private final boolean exists ;
private final Supplier < InputStreamSource > existingContent ;
protected FileHandler ( boolean exists , Supplier < InputStreamSource > existingContent ) {
this . exists = exists ;
this . existingContent = existingContent ;
}
/ * *
* Specify whether the file already exists .
* @return { @code true } if the file already exists
* /
public boolean exists ( ) {
return this . exists ;
}
/ * *
* Return an { @link InputStreamSource } for the content of the file or
* { @code null } if the file does not exist .
* /
@Nullable
public InputStreamSource getContent ( ) {
return ( exists ( ) ? this . existingContent . get ( ) : null ) ;
}
/ * *
* Create a file with the given { @linkplain InputStreamSource content } .
* @throws IllegalStateException if the file already exists
* /
public void create ( InputStreamSource content ) {
Assert . notNull ( content , "'content' must not be null" ) ;
if ( exists ( ) ) {
throw new IllegalStateException ( "%s already exists" . formatted ( this ) ) ;
}
copy ( content , false ) ;
}
/ * *
* Override the content of the file handled by this instance using the
* given { @linkplain InputStreamSource content } . If the file does not
* exist , it is created .
* /
public void override ( InputStreamSource content ) {
Assert . notNull ( content , "'content' must not be null" ) ;
copy ( content , true ) ;
}
protected abstract void copy ( InputStreamSource content , boolean override ) ;
}
}