From 18a666caf881bd4bb9e14216be90bfc47930ba27 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 10 Jan 2014 12:27:23 -0800 Subject: [PATCH] Replaces references to 'files' with 'sources' Replace references to 'files' throughout the code-base with 'sources' following the rename of `FileOptions` to `SourceOptions`. Also cleanup ResourceUtils a little --- .../boot/cli/command/GrabCommand.java | 4 +- .../boot/cli/command/InitCommand.java | 8 +- .../boot/cli/command/RunCommand.java | 6 +- .../boot/cli/command/SourceOptions.java | 1 - .../boot/cli/command/TestCommand.java | 6 +- .../boot/cli/compiler/GroovyCompiler.java | 1 + .../cli/runner/SpringApplicationRunner.java | 36 ++-- .../boot/cli/testrunner/TestRunner.java | 12 +- .../boot/cli/util/ResourceUtils.java | 196 ++++++++++-------- .../boot/cli/util/ResourceUtilsTests.java | 2 + 10 files changed, 150 insertions(+), 122 deletions(-) diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/GrabCommand.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/GrabCommand.java index 4f4cf8f508a..25f4c690e78 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/GrabCommand.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/GrabCommand.java @@ -43,7 +43,7 @@ public class GrabCommand extends OptionParsingCommand { @Override protected void run(OptionSet options) throws Exception { - SourceOptions fileOptions = new SourceOptions(options); + SourceOptions sourceOptions = new SourceOptions(options); List repositoryConfiguration = RepositoryConfigurationFactory .createDefaultRepositoryConfiguration(); @@ -56,7 +56,7 @@ public class GrabCommand extends OptionParsingCommand { } GroovyCompiler groovyCompiler = new GroovyCompiler(configuration); - groovyCompiler.compile(fileOptions.getSourcesArray()); + groovyCompiler.compile(sourceOptions.getSourcesArray()); } } diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/InitCommand.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/InitCommand.java index 0b29193700a..ab50ca7b680 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/InitCommand.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/InitCommand.java @@ -75,9 +75,9 @@ public class InitCommand extends OptionParsingCommand { ClassLoader loader = Thread.currentThread().getContextClassLoader(); boolean enhanced = false; - SourceOptions fileOptions = new SourceOptions(options, loader, "init.groovy", + SourceOptions sourceOptions = new SourceOptions(options, loader, "init.groovy", "spring.groovy"); - String[] files = fileOptions.getSourcesArray(); + String[] sources = sourceOptions.getSourcesArray(); if (!(loader instanceof GroovyClassLoader)) { @@ -102,8 +102,8 @@ public class InitCommand extends OptionParsingCommand { } } - if (this.compiler != null && files.length > 0) { - Class[] classes = this.compiler.compile(files); + if (this.compiler != null && sources.length > 0) { + Class[] classes = this.compiler.compile(sources); for (Class type : classes) { Command script = ScriptCommand.command(type); if (script != null) { diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/RunCommand.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/RunCommand.java index ab4574fdb5e..c83efb84e52 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/RunCommand.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/RunCommand.java @@ -95,10 +95,10 @@ public class RunCommand extends OptionParsingCommand { "Already running. Please stop the current application before running another."); } - SourceOptions fileOptions = new SourceOptions(options); + SourceOptions sourceOptions = new SourceOptions(options); if (options.has(this.editOption)) { - Desktop.getDesktop().edit(new File(fileOptions.getSources().get(0))); + Desktop.getDesktop().edit(new File(sourceOptions.getSources().get(0))); } List repositoryConfiguration = RepositoryConfigurationFactory @@ -110,7 +110,7 @@ public class RunCommand extends OptionParsingCommand { options, this, repositoryConfiguration); this.runner = new SpringApplicationRunner(configuration, - fileOptions.getSourcesArray(), fileOptions.getArgsArray()); + sourceOptions.getSourcesArray(), sourceOptions.getArgsArray()); this.runner.compileAndRun(); } diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/SourceOptions.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/SourceOptions.java index 2c93a449027..5f4b218fc74 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/SourceOptions.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/SourceOptions.java @@ -51,7 +51,6 @@ public class SourceOptions { * paths are tested before use). If default paths are provided and the option set * contains no source file arguments it is not an error even if none of the default * paths exist). - * * @param optionSet the source option set * @param classLoader an optional classloader used to try and load files that are not * found in the local filesystem diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/TestCommand.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/TestCommand.java index 6f638235c56..260d3bfbb91 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/TestCommand.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/TestCommand.java @@ -46,11 +46,11 @@ public class TestCommand extends OptionParsingCommand { @Override protected void run(OptionSet options) throws Exception { - SourceOptions fileOptions = new SourceOptions(options); + SourceOptions sourceOptions = new SourceOptions(options); TestRunnerConfiguration configuration = new TestRunnerConfigurationAdapter( options, this); - this.runner = new TestRunner(configuration, fileOptions.getSourcesArray(), - fileOptions.getArgsArray()); + this.runner = new TestRunner(configuration, sourceOptions.getSourcesArray(), + sourceOptions.getArgsArray()); this.runner.compileAndRunTests(); } diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java index e6517a49ea9..ab7b2f20667 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java @@ -304,4 +304,5 @@ public class GroovyCompiler { } } + } diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/runner/SpringApplicationRunner.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/runner/SpringApplicationRunner.java index 63e219f9ce1..72ffa954fcd 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/runner/SpringApplicationRunner.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/runner/SpringApplicationRunner.java @@ -25,7 +25,7 @@ import org.springframework.boot.cli.compiler.GroovyCompiler; /** * Compiles Groovy code running the resulting classes using a {@code SpringApplication}. - * Takes care of threading and class-loading issues and can optionally monitor files for + * Takes care of threading and class-loading issues and can optionally monitor sources for * changes. * * @author Phillip Webb @@ -39,7 +39,7 @@ public class SpringApplicationRunner { private final SpringApplicationRunnerConfiguration configuration; - private final String[] files; + private final String[] sources; private final String[] args; @@ -52,14 +52,14 @@ public class SpringApplicationRunner { /** * Create a new {@link SpringApplicationRunner} instance. * @param configuration the configuration - * @param files the files to compile/watch + * @param sources the files to compile/watch * @param args input arguments */ public SpringApplicationRunner( - final SpringApplicationRunnerConfiguration configuration, String[] files, + final SpringApplicationRunnerConfiguration configuration, String[] sources, String... args) { this.configuration = configuration; - this.files = files.clone(); + this.sources = sources.clone(); this.args = args.clone(); this.compiler = new GroovyCompiler(configuration); if (configuration.getLogLevel().intValue() <= Level.FINE.intValue()) { @@ -78,13 +78,13 @@ public class SpringApplicationRunner { stop(); // Compile - Object[] sources = this.compiler.sources(this.files); - if (sources.length == 0) { - throw new RuntimeException("No classes found in '" + this.files + "'"); + Object[] compiledSources = this.compiler.sources(this.sources); + if (compiledSources.length == 0) { + throw new RuntimeException("No classes found in '" + this.sources + "'"); } // Run in new thread to ensure that the context classloader is setup - this.runThread = new RunThread(sources); + this.runThread = new RunThread(compiledSources); this.runThread.start(); this.runThread.join(); @@ -111,19 +111,19 @@ public class SpringApplicationRunner { */ private class RunThread extends Thread { - private final Object[] sources; + private final Object[] compiledSources; private Object applicationContext; /** * Create a new {@link RunThread} instance. - * @param sources the sources to launch + * @param compiledSources the sources to launch */ - public RunThread(Object... sources) { + public RunThread(Object... compiledSources) { super("runner-" + (runnerCounter++)); - this.sources = sources; - if (sources.length != 0 && sources[0] instanceof Class) { - setContextClassLoader(((Class) sources[0]).getClassLoader()); + this.compiledSources = compiledSources; + if (compiledSources.length != 0 && compiledSources[0] instanceof Class) { + setContextClassLoader(((Class) compiledSources[0]).getClassLoader()); } setDaemon(true); } @@ -136,7 +136,7 @@ public class SpringApplicationRunner { "org.springframework.boot.SpringApplication"); Method method = application.getMethod("run", Object[].class, String[].class); - this.applicationContext = method.invoke(null, this.sources, + this.applicationContext = method.invoke(null, this.compiledSources, SpringApplicationRunner.this.args); } catch (Exception ex) { @@ -176,7 +176,7 @@ public class SpringApplicationRunner { public FileWatchThread() { super("filewatcher-" + (watcherCounter++)); this.previous = 0; - for (String path : SpringApplicationRunner.this.files) { + for (String path : SpringApplicationRunner.this.sources) { File file = new File(path); if (file.exists()) { long current = file.lastModified(); @@ -193,7 +193,7 @@ public class SpringApplicationRunner { while (true) { try { Thread.sleep(TimeUnit.SECONDS.toMillis(1)); - for (String path : SpringApplicationRunner.this.files) { + for (String path : SpringApplicationRunner.this.sources) { File file = new File(path); if (file.exists()) { long current = file.lastModified(); diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/testrunner/TestRunner.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/testrunner/TestRunner.java index 7763487f5d5..8a980c7aa24 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/testrunner/TestRunner.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/testrunner/TestRunner.java @@ -33,25 +33,25 @@ public class TestRunner { private static final String JUNIT_TEST_ANNOTATION = "org.junit.Test"; - private final String[] files; + private final String[] sources; private final GroovyCompiler compiler; /** * Create a new {@link TestRunner} instance. * @param configuration - * @param files + * @param sources * @param args */ - public TestRunner(TestRunnerConfiguration configuration, String[] files, String[] args) { - this.files = files.clone(); + public TestRunner(TestRunnerConfiguration configuration, String[] sources, String[] args) { + this.sources = sources.clone(); this.compiler = new GroovyCompiler(configuration); } public void compileAndRunTests() throws Exception { - Object[] sources = this.compiler.sources(this.files); + Object[] sources = this.compiler.sources(this.sources); if (sources.length == 0) { - throw new RuntimeException("No classes found in '" + this.files + "'"); + throw new RuntimeException("No classes found in '" + this.sources + "'"); } // Run in new thread to ensure that the context classloader is setup diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/ResourceUtils.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/ResourceUtils.java index ee930b289f7..7b0b9652703 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/ResourceUtils.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/ResourceUtils.java @@ -17,7 +17,6 @@ package org.springframework.boot.cli.util; import java.io.IOException; -import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; @@ -35,21 +34,38 @@ import org.springframework.util.StringUtils; * Utilities for manipulating resource paths and URLs. * * @author Dave Syer + * @author Phillip Webb */ public abstract class ResourceUtils { - /** Pseudo URL prefix for loading from the class path: "classpath:" */ + /** + * Pseudo URL prefix for loading from the class path: "classpath:" + */ public static final String CLASSPATH_URL_PREFIX = "classpath:"; - /** Pseudo URL prefix for loading all resources from the class path: "classpath*:" */ + /** + * Pseudo URL prefix for loading all resources from the class path: "classpath*:" + */ public static final String ALL_CLASSPATH_URL_PREFIX = "classpath*:"; - /** URL prefix for loading from the file system: "file:" */ + /** + * URL prefix for loading from the file system: "file:" + */ public static final String FILE_URL_PREFIX = "file:"; - /** Wildcard character in source path */ - public static final CharSequence WILDCARD = "*"; + /** + * Wildcard character in source path + */ + private static final CharSequence WILDCARD = "*"; + /** + * Return URLs from a given source path. Source paths can be simple file locations + * (/some/file.java) or wildcard patterns (/some/**). Additionally the prefixes + * "file:", "classpath:" and "classpath*:" can be used for specific path types. + * @param path the source path + * @param classLoader the class loader or {@code null} to use the default + * @return a list of URLs + */ public static List getUrls(String path, ClassLoader classLoader) { if (classLoader == null) { @@ -57,60 +73,103 @@ public abstract class ResourceUtils { } path = StringUtils.cleanPath(path); - if (path.contains(WILDCARD)) { + + try { + if (path.contains(WILDCARD)) { + return getUrlsFromWildcardPath(path, classLoader); + } + if (path.contains(":")) { - try { - Resource[] resources = new PathMatchingResourcePatternResolver( - classLoader).getResources(path); - List result = new ArrayList(); - for (Resource resource : resources) { - result.add(resource.getURL().toExternalForm()); - } - return result; - } - catch (IOException e) { - throw new IllegalArgumentException("Cannot resolve paths at [" + path - + "]", e); - } - } - else { - try { - return getUrls(FILE_URL_PREFIX + path, classLoader); - } - catch (IllegalArgumentException e) { - // ignore - } - return getUrls(ALL_CLASSPATH_URL_PREFIX + path, classLoader); - } - } - - if (path.contains(":")) { - - if (path.startsWith(CLASSPATH_URL_PREFIX)) { - path = path.substring(CLASSPATH_URL_PREFIX.length()); - } - else { - return getFilePath(path); + return getUrlsFromPrefixedPath(path, classLoader); } - } - else { try { - return getFilePath(path); + return getUrlsFromFile(path); } - catch (IllegalArgumentException e) { + catch (IOException ex) { // ignore } + + return getUrlsFromResources(path, classLoader); + } + catch (Exception ex) { + throw new IllegalArgumentException("Cannot create URL from path [" + path + + "]", ex); + + } + } + + private static List getUrlsFromWildcardPath(String path, + ClassLoader classLoader) throws IOException { + if (path.contains(":")) { + return getUrlsFromPrefixedWildcardPath(path, classLoader); } - while (path.startsWith("/")) { - path = path.substring(1); + try { + return getUrls(FILE_URL_PREFIX + path, classLoader); } + catch (IllegalArgumentException ex) { + // ignore + } + + return getUrls(ALL_CLASSPATH_URL_PREFIX + path, classLoader); + } + + private static List getUrlsFromPrefixedWildcardPath(String path, + ClassLoader classLoader) throws IOException { + Resource[] resources = new PathMatchingResourcePatternResolver(classLoader) + .getResources(path); + List result = new ArrayList(); + for (Resource resource : resources) { + result.add(resource.getURL().toExternalForm()); + } + return result; + } + + private static List getUrlsFromPrefixedPath(String path, + ClassLoader classLoader) throws IOException { + if (path.startsWith(CLASSPATH_URL_PREFIX)) { + return getUrlsFromResources(path.substring(CLASSPATH_URL_PREFIX.length()), + classLoader); + } + return getUrlsFromFile(path); + } + + private static List getUrlsFromFile(String path) throws IOException { + Resource resource = new FileSystemResource(path); + if (resource.exists()) { + if (resource.getFile().isDirectory()) { + return getChildFiles(resource); + } + return Collections.singletonList(resource.getURL().toExternalForm()); + } + + resource = new UrlResource(path); + if (resource.exists()) { + return Collections.singletonList(resource.getURL().toExternalForm()); + } + + return Collections.emptyList(); + } + + private static List getChildFiles(Resource resource) throws IOException { + Resource[] children = new PathMatchingResourcePatternResolver() + .getResources(resource.getURL() + "/**"); + List childFiles = new ArrayList(); + for (Resource child : children) { + if (!child.getFile().isDirectory()) { + childFiles.add(child.getURL().toExternalForm()); + } + } + return childFiles; + } + + private static List getUrlsFromResources(String path, ClassLoader classLoader) { + path = stripLeadingSlashes(path); List result = new ArrayList(); if (classLoader != null) { - Enumeration urls; try { - urls = classLoader.getResources(path); + Enumeration urls = classLoader.getResources(path); while (urls.hasMoreElements()) { URL url = urls.nextElement(); result.add(url.toExternalForm()); @@ -123,44 +182,11 @@ public abstract class ResourceUtils { return result; } - private static List getFilePath(String path) { - FileSystemResource resource = new FileSystemResource(path); - if (resource.exists()) { - try { - if (resource.getFile().isDirectory()) { - Resource[] resources = new PathMatchingResourcePatternResolver() - .getResources(resource.getURL() + "/**"); - List result = new ArrayList(); - for (Resource sub : resources) { - if (!sub.getFile().isDirectory()) { - result.add(sub.getURL().toExternalForm()); - } - } - return result; - } - return Collections.singletonList(resource.getURL().toExternalForm()); - } - catch (IOException e) { - throw new IllegalArgumentException("Cannot create URL from path [" + path - + "]", e); - } + private static String stripLeadingSlashes(String path) { + while (path.startsWith("/")) { + path = path.substring(1); } - try { - UrlResource url = new UrlResource(path); - if (url.exists()) { - try { - return Collections.singletonList(url.getURL().toExternalForm()); - } - catch (IOException e) { - throw new IllegalArgumentException("Cannot create URL from path [" - + path + "]", e); - } - } - } - catch (MalformedURLException ex) { - throw new IllegalArgumentException("Cannot create URL from path [" + path - + "]", ex); - } - return Collections.emptyList(); + return path; } + } diff --git a/spring-boot-cli/src/test/java/org/springframework/boot/cli/util/ResourceUtilsTests.java b/spring-boot-cli/src/test/java/org/springframework/boot/cli/util/ResourceUtilsTests.java index 3658b4b6c24..a60ff93aa2f 100644 --- a/spring-boot-cli/src/test/java/org/springframework/boot/cli/util/ResourceUtilsTests.java +++ b/spring-boot-cli/src/test/java/org/springframework/boot/cli/util/ResourceUtilsTests.java @@ -25,6 +25,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** + * Tests for {@link ResourceUtils}. + * * @author Dave Syer */ public class ResourceUtilsTests {