Improve SourceStructure to handle source and resource assets

This commit is contained in:
Stephane Nicoll
2019-09-02 10:19:09 +02:00
parent 595050258c
commit 7d47786a8b
5 changed files with 116 additions and 50 deletions

View File

@@ -29,14 +29,17 @@ public class SourceStructure {
private final Path rootDirectory;
private final Language language;
private final String sourceFileExtension;
private final Path sourcesDirectory;
private final Path resourcesDirectory;
public SourceStructure(Path rootDirectory, Language language) {
this.rootDirectory = rootDirectory;
this.language = language;
this.sourceFileExtension = language.sourceFileExtension();
this.sourcesDirectory = rootDirectory.resolve(language.id());
this.resourcesDirectory = rootDirectory.resolve("resources");
}
/**
@@ -50,42 +53,82 @@ public class SourceStructure {
/**
* Return the sources {@link Path directory} of this structure.
* @return the source code directory
* @return the sources directory
*/
public Path getSourcesDirectory() {
return this.sourcesDirectory;
}
/**
* Resolve a source file, creating its package structure if necessary. Does not create
* the file itself.
* Return the resources {@link Path directory} of this structure.
* @return the resources directory
*/
public Path getResourcesDirectory() {
return this.resourcesDirectory;
}
/**
* Resolve a source file.
* @param packageName the name of the package
* @param fileName the name of the file (without its extension)
* @return the {@link Path file} to use to store a {@code CompilationUnit} with the
* specified package and name
* @see #getSourcesDirectory()
*/
public Path resolveSourceFile(String packageName, String fileName) {
String file = fileName + "." + this.sourceFileExtension;
return resolvePackage(this.sourcesDirectory, packageName).resolve(file);
}
/**
* Create a source file, creating its package structure if necessary.
* @param packageName the name of the package
* @param fileName the name of the file (without its extension)
* @return the {@link Path file} to use to store a {@code CompilationUnit} with the
* specified package and name
* @throws IOException if an error occurred while trying to create the directory
* structure
* structure or the file itself
* @see #getSourcesDirectory()
*/
public Path resolveSourceFile(String packageName, String fileName) throws IOException {
String file = fileName + "." + this.language.sourceFileExtension();
return createPackage(this.sourcesDirectory, packageName).resolve(file);
public Path createSourceFile(String packageName, String fileName) throws IOException {
Path sourceFile = resolveSourceFile(packageName, fileName);
createFile(sourceFile);
return sourceFile;
}
/**
* Create the specified package if necessary.
* @param srcDirectory the source directory for the package
* @param packageName the name of the package to create
* @return the directory where source for this package should reside
* @throws IOException if an error occurred while trying to create the directory
* structure
* Resolve a resource file defined in the specified package.
* @param packageName the name of the package
* @param file the name of the file (including its extension)
* @return the {@link Path file} to use to store a resource with the specified package
* @see #getResourcesDirectory()
*/
protected Path createPackage(Path srcDirectory, String packageName) throws IOException {
if (!Files.exists(srcDirectory)) {
Files.createDirectories(srcDirectory);
}
Path directory = srcDirectory.resolve(packageName.replace('.', '/'));
Files.createDirectories(directory);
return directory;
public Path resolveResourceFile(String packageName, String file) {
return resolvePackage(this.resourcesDirectory, packageName).resolve(file);
}
/**
* Create a resource file, creating its package structure if necessary.
* @param packageName the name of the package
* @param file the name of the file (including its extension)
* @return the {@link Path file} to use to store a resource with the specified package
* @throws IOException if an error occurred while trying to create the directory
* structure or the file itself
* @see #getResourcesDirectory()
*/
public Path createResourceFile(String packageName, String file) throws IOException {
Path resourceFile = resolveResourceFile(packageName, file);
createFile(resourceFile);
return resourceFile;
}
private void createFile(Path file) throws IOException {
Files.createDirectories(file.getParent());
Files.createFile(file);
}
private static Path resolvePackage(Path directory, String packageName) {
return directory.resolve(packageName.replace('.', '/'));
}
}

View File

@@ -95,7 +95,7 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
}
private void writeTo(SourceStructure structure, GroovyCompilationUnit compilationUnit) throws IOException {
Path output = structure.resolveSourceFile(compilationUnit.getPackageName(), compilationUnit.getName());
Path output = structure.createSourceFile(compilationUnit.getPackageName(), compilationUnit.getName());
try (IndentingWriter writer = this.indentingWriterFactory.createIndentingWriter("groovy",
Files.newBufferedWriter(output))) {
writer.println("package " + compilationUnit.getPackageName());

View File

@@ -96,7 +96,7 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
}
private void writeTo(SourceStructure structure, JavaCompilationUnit compilationUnit) throws IOException {
Path output = structure.resolveSourceFile(compilationUnit.getPackageName(), compilationUnit.getName());
Path output = structure.createSourceFile(compilationUnit.getPackageName(), compilationUnit.getName());
Files.createDirectories(output.getParent());
try (IndentingWriter writer = this.indentingWriterFactory.createIndentingWriter("java",
Files.newBufferedWriter(output))) {

View File

@@ -61,7 +61,7 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
}
private void writeTo(SourceStructure structure, KotlinCompilationUnit compilationUnit) throws IOException {
Path output = structure.resolveSourceFile(compilationUnit.getPackageName(), compilationUnit.getName());
Path output = structure.createSourceFile(compilationUnit.getPackageName(), compilationUnit.getName());
Files.createDirectories(output.getParent());
try (IndentingWriter writer = this.indentingWriterFactory.createIndentingWriter("kotlin",
Files.newBufferedWriter(output))) {

View File

@@ -36,41 +36,64 @@ class SourceStructureTests {
public static final JavaLanguage JAVA_LANGUAGE = new JavaLanguage();
@Test
void createPackage(@TempDir Path dir) throws IOException {
Path target = new SourceStructure(dir, JAVA_LANGUAGE).createPackage(dir, "com.example.test");
assertThat(target).exists().isDirectory().isEqualByComparingTo(dir.resolve("com/example/test"));
}
@Test
void createExistingPackageReturnsExistingDirectory(@TempDir Path dir) throws IOException {
Path target = dir.resolve("com/example");
Files.createDirectories(target);
assertThat(target).exists().isDirectory();
Path path = new SourceStructure(dir, JAVA_LANGUAGE).createPackage(dir, "com.example");
assertThat(path).isEqualByComparingTo(target);
}
@Test
void resolveSourceFile(@TempDir Path dir) throws IOException {
Path rootDir = dir.resolve("src/main/java/com/example");
assertThat(rootDir).doesNotExist();
Path target = rootDir.resolve("Test.java");
void createSourceFile(@TempDir Path dir) throws IOException {
Path target = dir.resolve("src/main/java/com/example/Test.java");
SourceStructure sourceStructure = new SourceStructure(dir.resolve("src/main"), JAVA_LANGUAGE);
Path path = sourceStructure.resolveSourceFile("com.example", "Test");
assertThat(path).doesNotExist().isEqualByComparingTo(target);
assertThat(rootDir).exists().isDirectory();
Path path = sourceStructure.createSourceFile("com.example", "Test");
assertThat(path).exists().isRegularFile().isEqualByComparingTo(target);
}
@Test
void resolveSourceFileWithExistingPackage(@TempDir Path dir) throws IOException {
void createSourceFileWithExistingPackage(@TempDir Path dir) throws IOException {
Path rootDir = dir.resolve("src/main/java/com/example");
Files.createDirectories(rootDir);
assertThat(rootDir).exists().isDirectory();
Path target = rootDir.resolve("Test.java");
assertThat(target).doesNotExist();
SourceStructure sourceStructure = new SourceStructure(dir.resolve("src/main"), JAVA_LANGUAGE);
Path path = sourceStructure.resolveSourceFile("com.example", "Test");
assertThat(path).doesNotExist().isEqualByComparingTo(target);
Path path = sourceStructure.createSourceFile("com.example", "Test");
assertThat(path).exists().isRegularFile().isEqualByComparingTo(target);
}
@Test
void resolveSourceWithPath(@TempDir Path dir) {
SourceStructure sourceStructure = new SourceStructure(dir.resolve("src/main"), JAVA_LANGUAGE);
Path configFile = sourceStructure.getSourcesDirectory().resolve("com/example/specific.xml");
assertThat(configFile).isEqualByComparingTo(dir.resolve("src/main/java/com/example/specific.xml"));
}
@Test
void createResourceFile(@TempDir Path dir) throws IOException {
Path target = dir.resolve("src/main/resources/com/example/test.xml");
SourceStructure sourceStructure = new SourceStructure(dir.resolve("src/main"), JAVA_LANGUAGE);
Path path = sourceStructure.createResourceFile("com.example", "test.xml");
assertThat(path).exists().isRegularFile().isEqualByComparingTo(target);
}
@Test
void createResourceFileWithExistingPackage(@TempDir Path dir) throws IOException {
Path rootDir = dir.resolve("src/main/resources/com/example");
Files.createDirectories(rootDir);
assertThat(rootDir).exists().isDirectory();
Path target = rootDir.resolve("test.properties");
assertThat(target).doesNotExist();
SourceStructure sourceStructure = new SourceStructure(dir.resolve("src/main"), JAVA_LANGUAGE);
Path path = sourceStructure.createResourceFile("com.example", "test.properties");
assertThat(path).exists().isRegularFile().isEqualByComparingTo(target);
}
@Test
void resolveResourceWithPath(@TempDir Path dir) {
SourceStructure sourceStructure = new SourceStructure(dir.resolve("src/main"), JAVA_LANGUAGE);
Path configFile = sourceStructure.getResourcesDirectory().resolve("config.xml");
assertThat(configFile).isEqualByComparingTo(dir.resolve("src/main/resources/config.xml"));
}
@Test
void resolveBuildResource(@TempDir Path dir) {
SourceStructure sourceStructure = new SourceStructure(dir.resolve("src/main"), JAVA_LANGUAGE);
Path configFile = sourceStructure.getRootDirectory().resolve("assembly/bundle.xml");
assertThat(configFile).isEqualByComparingTo(dir.resolve("src/main/assembly/bundle.xml"));
}
}