This commit is contained in:
Phillip Webb
2015-09-05 10:38:30 -07:00
parent 67402405db
commit 6e29ee4557
125 changed files with 638 additions and 506 deletions

View File

@@ -34,7 +34,10 @@ import org.springframework.boot.loader.tools.LogbackInitializer;
* @see #main(String...)
* @see CommandRunner
*/
public class SpringCli {
public final class SpringCli {
private SpringCli() {
}
public static void main(String... args) {
System.setProperty("java.awt.headless", Boolean.toString(true));

View File

@@ -219,6 +219,7 @@ class InitializrService {
}
}
catch (Exception ex) {
// Ignore
}
}
return null;

View File

@@ -220,7 +220,7 @@ class InitializrServiceMetadata {
return result;
}
private static class MetadataHolder<K, T> {
private final static class MetadataHolder<K, T> {
private final Map<K, T> content;

View File

@@ -90,6 +90,7 @@ class ProjectGenerator {
return ZIP_MIME_TYPE.equals(entity.getContentType().getMimeType());
}
catch (Exception ex) {
// Ignore
}
}
return false;

View File

@@ -16,9 +16,9 @@
package org.springframework.boot.cli.command.options;
import joptsimple.OptionSpec;
import java.util.Arrays;
import static java.util.Arrays.asList;
import joptsimple.OptionSpec;
/**
* An {@link OptionHandler} for commands that result in the compilation of one or more
@@ -46,7 +46,7 @@ public class CompilerOptionHandler extends OptionHandler {
this.autoconfigureOption = option("autoconfigure",
"Add autoconfigure compiler transformations").withOptionalArg()
.ofType(Boolean.class).defaultsTo(true);
this.classpathOption = option(asList("classpath", "cp"),
this.classpathOption = option(Arrays.asList("classpath", "cp"),
"Additional classpath entries").withRequiredArg();
doOptions();
}

View File

@@ -17,6 +17,7 @@
package org.springframework.boot.cli.command.run;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
@@ -33,8 +34,6 @@ import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import static java.util.Arrays.asList;
/**
* {@link Command} to 'run' a groovy script or scripts.
*
@@ -73,9 +72,9 @@ public class RunCommand extends OptionParsingCommand {
@Override
protected void doOptions() {
this.watchOption = option("watch", "Watch the specified file for changes");
this.verboseOption = option(asList("verbose", "v"),
this.verboseOption = option(Arrays.asList("verbose", "v"),
"Verbose logging of dependency resolution");
this.quietOption = option(asList("quiet", "q"), "Quiet logging");
this.quietOption = option(Arrays.asList("quiet", "q"), "Quiet logging");
}
public synchronized void stop() {

View File

@@ -17,6 +17,7 @@
package org.springframework.boot.cli.command.run;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
@@ -89,22 +90,9 @@ public class SpringApplicationRunner {
*/
public synchronized void compileAndRun() throws Exception {
try {
stop();
// Compile
Object[] compiledSources = this.compiler.compile(this.sources);
if (compiledSources.length == 0) {
throw new RuntimeException("No classes found in '" + this.sources + "'");
}
// Start monitoring for changes
if (this.fileWatchThread == null
&& this.configuration.isWatchForFileChanges()) {
this.fileWatchThread = new FileWatchThread();
this.fileWatchThread.start();
}
Object[] compiledSources = compile();
monitorForChanges();
// Run in new thread to ensure that the context classloader is setup
this.runThread = new RunThread(compiledSources);
this.runThread.start();
@@ -120,6 +108,28 @@ public class SpringApplicationRunner {
}
}
public void stop() {
if (this.runThread != null) {
this.runThread.shutdown();
this.runThread = null;
}
}
private Object[] compile() throws IOException {
Object[] compiledSources = this.compiler.compile(this.sources);
if (compiledSources.length == 0) {
throw new RuntimeException("No classes found in '" + this.sources + "'");
}
return compiledSources;
}
private void monitorForChanges() {
if (this.fileWatchThread == null && this.configuration.isWatchForFileChanges()) {
this.fileWatchThread = new FileWatchThread();
this.fileWatchThread.start();
}
}
/**
* Thread used to launch the Spring Application with the correct context classloader.
*/
@@ -246,11 +256,4 @@ public class SpringApplicationRunner {
}
public void stop() {
if (this.runThread != null) {
this.runThread.shutdown();
this.runThread = null;
}
}
}

View File

@@ -19,6 +19,7 @@ package org.springframework.boot.cli.compiler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.codehaus.groovy.ast.AnnotatedNode;
@@ -147,32 +148,44 @@ public abstract class AstUtils {
*/
public static ClosureExpression getClosure(BlockStatement block, String name,
boolean remove) {
for (Statement statement : new ArrayList<Statement>(block.getStatements())) {
if (statement instanceof ExpressionStatement) {
Expression expression = ((ExpressionStatement) statement).getExpression();
if (expression instanceof MethodCallExpression) {
MethodCallExpression call = (MethodCallExpression) expression;
Expression methodCall = call.getMethod();
if (methodCall instanceof ConstantExpression) {
ConstantExpression method = (ConstantExpression) methodCall;
if (name.equals(method.getValue())) {
ArgumentListExpression arguments = (ArgumentListExpression) call
.getArguments();
if (remove) {
block.getStatements().remove(statement);
}
ClosureExpression closure = (ClosureExpression) arguments
.getExpression(0);
return closure;
}
for (ExpressionStatement statement : getExpressionStatements(block)) {
Expression expression = statement.getExpression();
if (expression instanceof MethodCallExpression) {
ClosureExpression closure = getClosure(name,
(MethodCallExpression) expression);
if (closure != null) {
if (remove) {
block.getStatements().remove(statement);
}
return closure;
}
}
}
return null;
}
private static List<ExpressionStatement> getExpressionStatements(BlockStatement block) {
ArrayList<ExpressionStatement> statements = new ArrayList<ExpressionStatement>();
for (Statement statement : block.getStatements()) {
if (statement instanceof ExpressionStatement) {
statements.add((ExpressionStatement) statement);
}
}
return statements;
}
private static ClosureExpression getClosure(String name,
MethodCallExpression expression) {
Expression method = expression.getMethod();
if (method instanceof ConstantExpression) {
if (name.equals(((ConstantExpression) method).getValue())) {
return (ClosureExpression) ((ArgumentListExpression) expression
.getArguments()).getExpression(0);
}
}
return null;
}
public static ClosureExpression getClosure(BlockStatement block, String name) {
return getClosure(block, name, false);
}

View File

@@ -200,7 +200,7 @@ public class GroovyCompiler {
for (Object loadedClass : collector.getLoadedClasses()) {
classes.add((Class<?>) loadedClass);
}
ClassNode mainClassNode = getMainClass(compilationUnit);
ClassNode mainClassNode = MainClass.get(compilationUnit);
Class<?> mainClass = null;
for (Class<?> loadedClass : classes) {
@@ -275,7 +275,7 @@ public class GroovyCompiler {
ImportCustomizer importCustomizer = new SmartImportCustomizer(source,
context, classNode);
ClassNode mainClassNode = getMainClass(source.getAST().getClasses());
ClassNode mainClassNode = MainClass.get(source.getAST().getClasses());
// Additional auto configuration
for (CompilerAutoConfiguration autoConfiguration : GroovyCompiler.this.compilerAutoConfigurations) {
@@ -300,22 +300,27 @@ public class GroovyCompiler {
}
@SuppressWarnings("unchecked")
private static ClassNode getMainClass(CompilationUnit source) {
return getMainClass(source.getAST().getClasses());
}
private static class MainClass {
private static ClassNode getMainClass(List<ClassNode> classes) {
for (ClassNode node : classes) {
if (AstUtils.hasAtLeastOneAnnotation(node, "Enable*AutoConfiguration")) {
return null; // No need to enhance this
}
if (AstUtils.hasAtLeastOneAnnotation(node, "*Controller", "Configuration",
"Component", "*Service", "Repository", "Enable*")) {
return node;
}
@SuppressWarnings("unchecked")
public static ClassNode get(CompilationUnit source) {
return get(source.getAST().getClasses());
}
return (classes.isEmpty() ? null : classes.get(0));
public static ClassNode get(List<ClassNode> classes) {
for (ClassNode node : classes) {
if (AstUtils.hasAtLeastOneAnnotation(node, "Enable*AutoConfiguration")) {
return null; // No need to enhance this
}
if (AstUtils
.hasAtLeastOneAnnotation(node, "*Controller", "Configuration",
"Component", "*Service", "Repository", "Enable*")) {
return node;
}
}
return (classes.isEmpty() ? null : classes.get(0));
}
}
}

View File

@@ -30,12 +30,15 @@ import org.springframework.boot.cli.app.SpringApplicationLauncher;
* @author Andy Wilkinson
* @author Phillip Webb
*/
public class PackagedSpringApplicationLauncher {
public final class PackagedSpringApplicationLauncher {
public static final String SOURCE_ENTRY = "Spring-Application-Source-Classes";
public static final String START_CLASS_ENTRY = "Start-Class";
private PackagedSpringApplicationLauncher() {
}
private void run(String[] args) throws Exception {
URLClassLoader classLoader = (URLClassLoader) Thread.currentThread()
.getContextClassLoader();

View File

@@ -27,7 +27,10 @@ import org.springframework.boot.cli.command.test.TestRunner;
* @author Phillip Webb
* @see TestRunner
*/
public class DelegateTestRunner {
public final class DelegateTestRunner {
private DelegateTestRunner() {
}
public static void run(Class<?>[] testClasses, Result result) {
JUnitCore jUnitCore = new JUnitCore();