diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/InstallCommand.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/InstallCommand.java index aaf1d41331..6edab81823 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/InstallCommand.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/InstallCommand.java @@ -19,18 +19,15 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; -import java.nio.file.FileVisitResult; -import java.nio.file.FileVisitor; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import joptsimple.OptionSet; import joptsimple.OptionSpec; -import org.codehaus.plexus.util.FileUtils; import org.springframework.boot.cli.command.Command; import org.springframework.boot.cli.command.OptionParsingCommand; import org.springframework.boot.cli.command.options.CompilerOptionHandler; @@ -41,36 +38,38 @@ import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory; import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; import org.springframework.boot.cli.util.Log; +import org.springframework.util.FileCopyUtils; import org.springframework.util.SystemPropertyUtils; /** * {@link Command} to install additional dependencies into the CLI. * * @author Dave Syer + * @author Andy Wilkinson */ public class InstallCommand extends OptionParsingCommand { public static Command install() { return new InstallCommand("install", "Install dependencies to lib directory", - new InstallFileVisitorFactory()); + new InstallFileProcessorFactory()); } public static Command uninstall() { return new InstallCommand("uninstall", "Uninstall dependencies from a lib directory", - new UninstallFileVisitorFactory()); + new UninstallFileProcessorFactory()); } - private InstallCommand(String name, String description, FileVisitorFactory visitor) { + private InstallCommand(String name, String description, FileProcessorFactory visitor) { super(name, description, new InstallOptionHandler(visitor)); } private static final class InstallOptionHandler extends CompilerOptionHandler { - private FileVisitorFactory factory; + private FileProcessorFactory factory; private OptionSpec allOption; - public InstallOptionHandler(FileVisitorFactory factory) { + public InstallOptionHandler(FileProcessorFactory factory) { this.factory = factory; } @@ -111,43 +110,60 @@ public class InstallCommand extends OptionParsingCommand { } }; - Path tmpdir = Files.createTempDirectory("SpringInstallCommand") - .toAbsolutePath(); - String grapeRoot = System.getProperty("grape.root"); - System.setProperty("grape.root", tmpdir.toString()); - GroovyCompiler groovyCompiler = new GroovyCompiler(configuration); try { if (!args.isEmpty()) { + List initialUrls = getClassPathUrls(groovyCompiler); groovyCompiler.compile(createSources(args)); - installJars(tmpdir); + List urlsToProcessor = getClassPathUrls(groovyCompiler); + urlsToProcessor.removeAll(initialUrls); + + processJars(urlsToProcessor); } - FileUtils.deleteDirectory(tmpdir.toFile()); } catch (Exception ex) { String message = ex.getMessage(); Log.error(message != null ? message : ex.getClass().toString()); } - finally { - if (grapeRoot != null) { - System.setProperty("grape.root", grapeRoot); - } - else { - System.clearProperty("grape.root"); - } - } return ExitStatus.OK; } - private void installJars(Path tmpdir) throws IOException { + private List getClassPathUrls(GroovyCompiler compiler) { + return new ArrayList(Arrays.asList(compiler.getLoader().getURLs())); + } + + private void processJars(List urlsToProcess) throws IOException { File lib = getDefaultLibDirectory(); - Files.walkFileTree(tmpdir, this.factory.visitor(lib)); + + FileProcessor processor = this.factory.processor(lib); + + for (URL url : urlsToProcess) { + File file = toFile(url); + if (file.getName().endsWith(".jar")) { + processor.processFile(file); + } + } + } + + private File toFile(URL url) { + try { + return new File(url.toURI()); + } + catch (URISyntaxException ex) { + return new File(url.getPath()); + } } private void uninstallAllJars() throws IOException { File lib = getDefaultLibDirectory(); - Files.walkFileTree(lib.toPath(), new DeleteNotTheCliVisitor()); + File[] filesInLib = lib.listFiles(); + if (filesInLib != null) { + FileProcessor processor = new DeleteNotTheCliProcessor(); + for (File file : filesInLib) { + processor.processFile(file); + } + } } private String createSources(List args) throws IOException { @@ -177,70 +193,51 @@ public class InstallCommand extends OptionParsingCommand { } - private interface FileVisitorFactory { - FileVisitor visitor(File lib); + private interface FileProcessorFactory { + FileProcessor processor(File lib); } - private static class DeleteNotTheCliVisitor extends SimpleFileVisitor { + private interface FileProcessor { + void processFile(File file) throws IOException; + } + + private static class DeleteNotTheCliProcessor implements FileProcessor { @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - String name = file.getFileName().toString(); - if (name.endsWith(".jar") && !name.startsWith("spring-boot-cli")) { - file.toFile().delete(); + public void processFile(File file) throws IOException { + if (!file.getName().startsWith("spring-boot-cli")) { + file.delete(); } - return FileVisitResult.CONTINUE; } + } - private static class InstallFileVisitorFactory implements FileVisitorFactory { + private static class InstallFileProcessorFactory implements FileProcessorFactory { @Override - public SimpleFileVisitor visitor(final File lib) { + public FileProcessor processor(final File lib) { Log.info("Installing into: " + lib); lib.mkdirs(); - return new SimpleFileVisitor() { + return new FileProcessor() { @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - if (file.getFileName().toString().endsWith(".jar")) { - Files.copy(file, new FileOutputStream(new File(lib, file - .getFileName().toString()))); - return FileVisitResult.SKIP_SIBLINGS; - } - return FileVisitResult.CONTINUE; + public void processFile(File file) throws IOException { + FileCopyUtils.copy(file, new File(lib, file.getName())); } }; } } - private static class UninstallFileVisitorFactory implements FileVisitorFactory { + private static class UninstallFileProcessorFactory implements FileProcessorFactory { @Override - public SimpleFileVisitor visitor(final File lib) { + public FileProcessor processor(final File lib) { Log.info("Uninstalling from: " + lib); - if (!lib.exists()) { - return new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - return FileVisitResult.TERMINATE; - } - }; - } - return new SimpleFileVisitor() { + return new FileProcessor() { @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - if (file.getFileName().toString().endsWith(".jar")) { - new File(lib, file.getFileName().toString()).delete(); - return FileVisitResult.SKIP_SIBLINGS; - } - return FileVisitResult.CONTINUE; + public void processFile(File file) throws IOException { + new File(lib, file.getName()).delete(); } }; - } }