Broaden usage of Path in place of File

Closes gh-950
This commit is contained in:
Andy Wilkinson
2019-07-11 12:16:33 +01:00
parent 449b22403a
commit aad9ce07d7
3 changed files with 35 additions and 40 deletions

View File

@@ -17,11 +17,12 @@
package io.spring.initializr.web.project; package io.spring.initializr.web.project;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -57,7 +58,6 @@ import org.springframework.http.ResponseEntity;
import org.springframework.http.ResponseEntity.BodyBuilder; import org.springframework.http.ResponseEntity.BodyBuilder;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestHeader;
@@ -222,7 +222,7 @@ public class MainController extends AbstractInitializrController {
public ResponseEntity<byte[]> springZip(ProjectRequest request) throws IOException { public ResponseEntity<byte[]> springZip(ProjectRequest request) throws IOException {
ProjectGenerationResult result = this.projectGenerationInvoker.invokeProjectStructureGeneration(request); ProjectGenerationResult result = this.projectGenerationInvoker.invokeProjectStructureGeneration(request);
File dir = result.getRootDirectory().toFile(); File dir = result.getRootDirectory().toFile();
File download = this.projectGenerationInvoker.createDistributionFile(dir, ".zip"); Path archive = this.projectGenerationInvoker.createDistributionFile(result.getRootDirectory(), ".zip");
String wrapperScript = getWrapperScript(result.getProjectDescription()); String wrapperScript = getWrapperScript(result.getProjectDescription());
Zip zip = new Zip(); Zip zip = new Zip();
zip.setProject(new Project()); zip.setProject(new Project());
@@ -239,9 +239,9 @@ public class MainController extends AbstractInitializrController {
set.createExclude().setName(wrapperScript); set.createExclude().setName(wrapperScript);
set.setDefaultexcludes(false); set.setDefaultexcludes(false);
zip.addFileset(set); zip.addFileset(set);
zip.setDestFile(download.getCanonicalFile()); zip.setDestFile(archive.toFile().getCanonicalFile());
zip.execute(); zip.execute();
return upload(download, dir, generateFileName(request, "zip"), "application/zip"); return upload(archive, result.getRootDirectory(), generateFileName(request, "zip"), "application/zip");
} }
@RequestMapping(path = "/starter.tgz", produces = "application/x-compress") @RequestMapping(path = "/starter.tgz", produces = "application/x-compress")
@@ -249,7 +249,7 @@ public class MainController extends AbstractInitializrController {
public ResponseEntity<byte[]> springTgz(ProjectRequest request) throws IOException { public ResponseEntity<byte[]> springTgz(ProjectRequest request) throws IOException {
ProjectGenerationResult result = this.projectGenerationInvoker.invokeProjectStructureGeneration(request); ProjectGenerationResult result = this.projectGenerationInvoker.invokeProjectStructureGeneration(request);
File dir = result.getRootDirectory().toFile(); File dir = result.getRootDirectory().toFile();
File download = this.projectGenerationInvoker.createDistributionFile(dir, ".tar.gz"); Path download = this.projectGenerationInvoker.createDistributionFile(result.getRootDirectory(), ".tar.gz");
String wrapperScript = getWrapperScript(result.getProjectDescription()); String wrapperScript = getWrapperScript(result.getProjectDescription());
Tar zip = new Tar(); Tar zip = new Tar();
zip.setProject(new Project()); zip.setProject(new Project());
@@ -264,12 +264,13 @@ public class MainController extends AbstractInitializrController {
set.setIncludes("**,"); set.setIncludes("**,");
set.createExclude().setName(wrapperScript); set.createExclude().setName(wrapperScript);
set.setDefaultexcludes(false); set.setDefaultexcludes(false);
zip.setDestFile(download.getCanonicalFile()); zip.setDestFile(download.toFile().getCanonicalFile());
Tar.TarCompressionMethod method = new Tar.TarCompressionMethod(); Tar.TarCompressionMethod method = new Tar.TarCompressionMethod();
method.setValue("gzip"); method.setValue("gzip");
zip.setCompression(method); zip.setCompression(method);
zip.execute(); zip.execute();
return upload(download, dir, generateFileName(request, "tar.gz"), "application/x-compress"); return upload(download, result.getRootDirectory(), generateFileName(request, "tar.gz"),
"application/x-compress");
} }
private String generateFileName(ProjectRequest request, String extension) { private String generateFileName(ProjectRequest request, String extension) {
@@ -290,10 +291,10 @@ public class MainController extends AbstractInitializrController {
return (description.getBaseDirectory() != null) ? description.getBaseDirectory() + "/" + script : script; return (description.getBaseDirectory() != null) ? description.getBaseDirectory() + "/" + script : script;
} }
private ResponseEntity<byte[]> upload(File download, File dir, String fileName, String contentType) private ResponseEntity<byte[]> upload(Path archive, Path dir, String fileName, String contentType)
throws IOException { throws IOException {
byte[] bytes = StreamUtils.copyToByteArray(new FileInputStream(download)); byte[] bytes = Files.readAllBytes(archive);
logger.info(String.format("Uploading: %s (%s bytes)", download, bytes.length)); logger.info(String.format("Uploading: %s (%s bytes)", archive, bytes.length));
ResponseEntity<byte[]> result = createResponseEntity(bytes, contentType, fileName); ResponseEntity<byte[]> result = createResponseEntity(bytes, contentType, fileName);
this.projectGenerationInvoker.cleanTempFiles(dir); this.projectGenerationInvoker.cleanTempFiles(dir);
return result; return result;

View File

@@ -16,7 +16,6 @@
package io.spring.initializr.web.project; package io.spring.initializr.web.project;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.nio.file.Path; import java.nio.file.Path;
@@ -57,7 +56,7 @@ public class ProjectGenerationInvoker {
private final ProjectRequestToDescriptionConverter converter; private final ProjectRequestToDescriptionConverter converter;
private transient Map<String, List<File>> temporaryFiles = new LinkedHashMap<>(); private transient Map<Path, List<Path>> temporaryFiles = new LinkedHashMap<>();
public ProjectGenerationInvoker(ApplicationContext parentApplicationContext, public ProjectGenerationInvoker(ApplicationContext parentApplicationContext,
ApplicationEventPublisher eventPublisher, ProjectRequestToDescriptionConverter converter) { ApplicationEventPublisher eventPublisher, ProjectRequestToDescriptionConverter converter) {
@@ -79,9 +78,7 @@ public class ProjectGenerationInvoker {
ProjectGenerator projectGenerator = new ProjectGenerator(( ProjectGenerator projectGenerator = new ProjectGenerator((
projectGenerationContext) -> customizeProjectGenerationContext(projectGenerationContext, metadata)); projectGenerationContext) -> customizeProjectGenerationContext(projectGenerationContext, metadata));
ProjectGenerationResult result = projectGenerator.generate(projectDescription, generateProject(request)); ProjectGenerationResult result = projectGenerator.generate(projectDescription, generateProject(request));
File file = result.getRootDirectory().toFile(); addTempFile(result.getRootDirectory(), result.getRootDirectory());
String name = file.getName();
addTempFile(name, file);
return result; return result;
} }
catch (ProjectGenerationException ex) { catch (ProjectGenerationException ex) {
@@ -134,13 +131,13 @@ public class ProjectGenerationInvoker {
* @param extension the extension to use for the new file * @param extension the extension to use for the new file
* @return the newly created file * @return the newly created file
*/ */
public File createDistributionFile(File dir, String extension) { public Path createDistributionFile(Path dir, String extension) {
File download = new File(dir.getParent(), dir.getName() + extension); Path download = dir.resolveSibling(dir.getFileName() + extension);
addTempFile(dir.getName(), download); addTempFile(dir, download);
return download; return download;
} }
private void addTempFile(String group, File file) { private void addTempFile(Path group, Path file) {
this.temporaryFiles.computeIfAbsent(group, (key) -> new ArrayList<>()).add(file); this.temporaryFiles.computeIfAbsent(group, (key) -> new ArrayList<>()).add(file);
} }
@@ -149,15 +146,15 @@ public class ProjectGenerationInvoker {
* @param dir the directory to clean * @param dir the directory to clean
* @see #createDistributionFile * @see #createDistributionFile
*/ */
public void cleanTempFiles(File dir) { public void cleanTempFiles(Path dir) {
List<File> tempFiles = this.temporaryFiles.remove(dir.getName()); List<Path> tempFiles = this.temporaryFiles.remove(dir);
if (!tempFiles.isEmpty()) { if (!tempFiles.isEmpty()) {
tempFiles.forEach((File file) -> { tempFiles.forEach((path) -> {
if (file.isDirectory()) { try {
FileSystemUtils.deleteRecursively(file); FileSystemUtils.deleteRecursively(path);
} }
else if (file.exists()) { catch (IOException ex) {
file.delete(); // Continue
} }
}); });
} }

View File

@@ -16,7 +16,7 @@
package io.spring.initializr.web.project; package io.spring.initializr.web.project;
import java.io.File; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List; import java.util.List;
@@ -88,10 +88,9 @@ public class ProjectGenerationInvokerTests {
request.initialize(metadata); request.initialize(metadata);
ProjectGenerationResult result = this.invoker.invokeProjectStructureGeneration(request); ProjectGenerationResult result = this.invoker.invokeProjectStructureGeneration(request);
new ProjectAssert(result.getRootDirectory()).isJavaProject(); new ProjectAssert(result.getRootDirectory()).isJavaProject();
File file = result.getRootDirectory().toFile(); Map<Path, List<Path>> tempFiles = (Map<Path, List<Path>>) ReflectionTestUtils.getField(this.invoker,
Map<String, List<File>> tempFiles = (Map<String, List<File>>) ReflectionTestUtils.getField(this.invoker,
"temporaryFiles"); "temporaryFiles");
assertThat(tempFiles.get(file.getName())).contains(file); assertThat(tempFiles.get(result.getRootDirectory())).contains(result.getRootDirectory());
verifyProjectSuccessfulEventFor(request); verifyProjectSuccessfulEventFor(request);
} }
@@ -152,23 +151,21 @@ public class ProjectGenerationInvokerTests {
void createDistributionDirectory(@TempDir Path tempDir) { void createDistributionDirectory(@TempDir Path tempDir) {
ProjectRequest request = new ProjectRequest(); ProjectRequest request = new ProjectRequest();
request.setType("gradle-project"); request.setType("gradle-project");
File dir = tempDir.toFile(); Path distributionFile = this.invoker.createDistributionFile(tempDir, ".zip");
File distributionFile = this.invoker.createDistributionFile(dir, ".zip"); assertThat(distributionFile.toString()).isEqualTo(tempDir + ".zip");
assertThat(distributionFile.toString()).isEqualTo(dir.toString() + ".zip"); Map<Path, List<Path>> tempFiles = (Map<Path, List<Path>>) ReflectionTestUtils.getField(this.invoker,
Map<String, List<File>> tempFiles = (Map<String, List<File>>) ReflectionTestUtils.getField(this.invoker,
"temporaryFiles"); "temporaryFiles");
assertThat(tempFiles.get(dir.getName())).contains(distributionFile); assertThat(tempFiles.get(tempDir)).contains(distributionFile);
} }
@Test @Test
void cleanupTempFilesShouldOnlyCleanupSpecifiedDir() { void cleanupTempFilesShouldOnlyCleanupSpecifiedDir() throws IOException {
WebProjectRequest request = new WebProjectRequest(); WebProjectRequest request = new WebProjectRequest();
request.initialize(metadata); request.initialize(metadata);
request.setType("gradle-project"); request.setType("gradle-project");
ProjectGenerationResult result = this.invoker.invokeProjectStructureGeneration(request); ProjectGenerationResult result = this.invoker.invokeProjectStructureGeneration(request);
File file = result.getRootDirectory().toFile(); this.invoker.cleanTempFiles(result.getRootDirectory());
this.invoker.cleanTempFiles(file); assertThat(result.getRootDirectory()).doesNotExist();
assertThat(file.listFiles()).isNull();
} }
private void setupContext() { private void setupContext() {