Commit 18a666ca authored by Phillip Webb's avatar Phillip Webb

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
parent 2c6231a0
......@@ -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> 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());
}
}
......
......@@ -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) {
......
......@@ -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> 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();
}
......
......@@ -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
......
......@@ -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();
}
......
......@@ -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();
......
......@@ -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
......
......@@ -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<String> 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<String> result = new ArrayList<String>();
for (Resource resource : resources) {
result.add(resource.getURL().toExternalForm());
}
return result;
}
catch (IOException e) {
throw new IllegalArgumentException("Cannot resolve paths at [" + path
+ "]", e);
}
return getUrlsFromPrefixedPath(path, classLoader);
}
else {
try {
return getUrls(FILE_URL_PREFIX + path, classLoader);
}
catch (IllegalArgumentException e) {
// ignore
}
return getUrls(ALL_CLASSPATH_URL_PREFIX + path, classLoader);
try {
return getUrlsFromFile(path);
}
catch (IOException ex) {
// ignore
}
return getUrlsFromResources(path, classLoader);
}
catch (Exception ex) {
throw new IllegalArgumentException("Cannot create URL from path [" + path
+ "]", ex);
}
}
private static List<String> getUrlsFromWildcardPath(String path,
ClassLoader classLoader) throws IOException {
if (path.contains(":")) {
return getUrlsFromPrefixedWildcardPath(path, classLoader);
}
if (path.startsWith(CLASSPATH_URL_PREFIX)) {
path = path.substring(CLASSPATH_URL_PREFIX.length());
}
else {
return getFilePath(path);
}
try {
return getUrls(FILE_URL_PREFIX + path, classLoader);
}
catch (IllegalArgumentException ex) {
// ignore
}
return getUrls(ALL_CLASSPATH_URL_PREFIX + path, classLoader);
}
private static List<String> getUrlsFromPrefixedWildcardPath(String path,
ClassLoader classLoader) throws IOException {
Resource[] resources = new PathMatchingResourcePatternResolver(classLoader)
.getResources(path);
List<String> result = new ArrayList<String>();
for (Resource resource : resources) {
result.add(resource.getURL().toExternalForm());
}
else {
try {
return getFilePath(path);
}
catch (IllegalArgumentException e) {
// ignore
return result;
}
private static List<String> 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<String> 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());
}
while (path.startsWith("/")) {
path = path.substring(1);
resource = new UrlResource(path);
if (resource.exists()) {
return Collections.singletonList(resource.getURL().toExternalForm());
}
return Collections.emptyList();
}
private static List<String> getChildFiles(Resource resource) throws IOException {
Resource[] children = new PathMatchingResourcePatternResolver()
.getResources(resource.getURL() + "/**");
List<String> childFiles = new ArrayList<String>();
for (Resource child : children) {
if (!child.getFile().isDirectory()) {
childFiles.add(child.getURL().toExternalForm());
}
}
return childFiles;
}
private static List<String> getUrlsFromResources(String path, ClassLoader classLoader) {
path = stripLeadingSlashes(path);
List<String> result = new ArrayList<String>();
if (classLoader != null) {
Enumeration<URL> urls;
try {
urls = classLoader.getResources(path);
Enumeration<URL> 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<String> getFilePath(String path) {
FileSystemResource resource = new FileSystemResource(path);
if (resource.exists()) {
try {
if (resource.getFile().isDirectory()) {
Resource[] resources = new PathMatchingResourcePatternResolver()
.getResources(resource.getURL() + "/**");
List<String> result = new ArrayList<String>();
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);
}
}
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);
private static String stripLeadingSlashes(String path) {
while (path.startsWith("/")) {
path = path.substring(1);
}
return Collections.emptyList();
return path;
}
}
......@@ -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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment