@ -17,30 +17,13 @@
@@ -17,30 +17,13 @@
package org.springframework.boot.cli.command ;
import groovy.lang.Closure ;
import groovy.lang.GroovyObjectSupport ;
import groovy.lang.MetaClass ;
import groovy.lang.MetaMethod ;
import groovy.lang.Script ;
import groovy.lang.GroovyObject ;
import java.io.File ;
import java.io.FileOutputStream ;
import java.io.IOException ;
import java.net.URL ;
import java.util.Collection ;
import java.util.Collections ;
import java.util.List ;
import joptsimple.OptionParser ;
import org.codehaus.groovy.control.CompilationFailedException ;
import org.springframework.boot.cli.Command ;
import org.springframework.boot.cli.OptionHelp ;
import org.springframework.boot.cli.compiler.GroovyCompiler ;
import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration ;
import org.springframework.boot.cli.compiler.GroovyCompilerScope ;
import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory ;
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration ;
import org.springframework.util.FileCopyUtils ;
/ * *
* { @link Command } to run a Groovy script .
@ -49,27 +32,28 @@ import org.springframework.util.FileCopyUtils;
@@ -49,27 +32,28 @@ import org.springframework.util.FileCopyUtils;
* /
public class ScriptCommand implements Command {
private static final String [ ] DEFAULT_PATHS = new String [ ] { "${SPRING_HOME}/ext" ,
"${SPRING_HOME}/bin" } ;
private String [ ] paths = DEFAULT_PATHS ;
private Class < ? > mainClass ;
private Object main ;
private String n ame;
private String defaultName ;
public ScriptCommand ( String script ) {
this . name = script ;
public ScriptCommand ( String name , Object main ) {
this . main = main ;
this . defaultName = name ;
}
@Override
public String getName ( ) {
if ( getMain ( ) instanceof Command ) {
return ( ( Command ) getMain ( ) ) . getName ( ) ;
if ( this . main instanceof Command ) {
return ( ( Command ) this . main ) . getName ( ) ;
}
return this . name ;
else if ( this . main instanceof GroovyObject ) {
GroovyObject object = ( GroovyObject ) this . main ;
if ( object . getMetaClass ( ) . hasProperty ( object , "name" ) ! = null ) {
return ( String ) object . getProperty ( "name" ) ;
}
}
return this . defaultName ;
}
@Override
@ -79,210 +63,73 @@ public class ScriptCommand implements Command {
@@ -79,210 +63,73 @@ public class ScriptCommand implements Command {
@Override
public String getDescription ( ) {
if ( getMain ( ) instanceof Command ) {
return ( ( Command ) getMain ( ) ) . getDescription ( ) ;
if ( this . main instanceof Command ) {
return ( ( Command ) this . main ) . getDescription ( ) ;
}
return this . n ame;
return this . defaultN ame;
}
@Override
public String getHelp ( ) {
if ( getMain ( ) instanceof OptionHandler ) {
return ( ( OptionHandler ) getMain ( ) ) . getHelp ( ) ;
if ( this . main instanceof OptionHandler ) {
return ( ( OptionHandler ) this . main ) . getHelp ( ) ;
}
if ( getMain ( ) instanceof Command ) {
return ( ( Command ) getMain ( ) ) . getHelp ( ) ;
if ( this . main instanceof Command ) {
return ( ( Command ) this . main ) . getHelp ( ) ;
}
return null ;
}
@Override
public Collection < OptionHelp > getOptionsHelp ( ) {
if ( getMain ( ) instanceof OptionHandler ) {
return ( ( OptionHandler ) getMain ( ) ) . getOptionsHelp ( ) ;
if ( this . main instanceof OptionHandler ) {
return ( ( OptionHandler ) this . main ) . getOptionsHelp ( ) ;
}
if ( getMain ( ) instanceof Command ) {
return ( ( Command ) getMain ( ) ) . getOptionsHelp ( ) ;
if ( this . main instanceof Command ) {
return ( ( Command ) this . main ) . getOptionsHelp ( ) ;
}
return Collections . emptyList ( ) ;
}
@Override
public void run ( String . . . args ) throws Exception {
run ( getMain ( ) , args ) ;
}
private void run ( Object main , String [ ] args ) throws Exception {
if ( main instanceof Command ) {
( ( Command ) main ) . run ( args ) ;
}
else if ( main instanceof OptionHandler ) {
( ( OptionHandler ) getMain ( ) ) . run ( args ) ;
if ( this . main instanceof Command ) {
( ( Command ) this . main ) . run ( args ) ;
}
else if ( main instanceof Closure ) {
( ( Closure < ? > ) main ) . call ( ( Object [ ] ) args ) ;
else if ( this . main instanceof OptionHandler ) {
( ( OptionHandler ) this . main ) . run ( args ) ;
}
else if ( main instanceof Runnabl e) {
( ( Runnable ) main ) . run ( ) ;
else if ( this . main instanceof Closure ) {
( ( Closure < ? > ) this . main ) . call ( ( Object [ ] ) args ) ;
}
else if ( main instanceof Script ) {
Script script = ( Script ) this . main ;
script . setProperty ( "args" , args ) ;
if ( this . main instanceof GroovyObjectSupport ) {
GroovyObjectSupport object = ( GroovyObjectSupport ) this . main ;
if ( object . getMetaClass ( ) . hasProperty ( object , "parser" ) ! = null ) {
OptionParser parser = ( OptionParser ) object . getProperty ( "parser" ) ;
if ( parser ! = null ) {
script . setProperty ( "options" , parser . parse ( args ) ) ;
}
}
}
Object result = script . run ( ) ;
run ( result , args ) ;
}
}
/ * *
* Paths to search for script files .
*
* @param paths the paths to set
* /
public void setPaths ( String [ ] paths ) {
this . paths = ( paths = = null ? null : paths . clone ( ) ) ;
}
@Override
public String getUsageHelp ( ) {
if ( getMain ( ) instanceof Command ) {
return ( ( Command ) getMain ( ) ) . getDescription ( ) ;
if ( this . main instanceof Command ) {
return ( ( Command ) this . main ) . getDescription ( ) ;
}
return "[options] <args>" ;
}
protected Object getMain ( ) {
if ( this . main = = null ) {
try {
this . main = getMainClass ( ) . newInstance ( ) ;
}
catch ( Exception ex ) {
throw new IllegalStateException ( "Cannot create main class: " + this . name ,
ex ) ;
}
if ( this . main instanceof OptionHandler ) {
( ( OptionHandler ) this . main ) . options ( ) ;
}
else if ( this . main instanceof GroovyObjectSupport ) {
GroovyObjectSupport object = ( GroovyObjectSupport ) this . main ;
MetaClass metaClass = object . getMetaClass ( ) ;
MetaMethod options = metaClass . getMetaMethod ( "options" , null ) ;
if ( options ! = null ) {
options . doMethodInvoke ( this . main , null ) ;
}
}
}
return this . main ;
}
public static ScriptCommand command ( Class < ? > type ) {
private void compile ( ) {
GroovyCompiler compiler = new GroovyCompiler ( new ScriptConfiguration ( ) ) ;
compiler . addCompilationCustomizers ( new ScriptCompilationCustomizer ( ) ) ;
File source = locateSource ( this . name ) ;
Class < ? > [ ] classes ;
Object main = null ;
try {
classes = compiler . compile ( source ) ;
}
catch ( CompilationFailedException ex ) {
throw new IllegalStateException ( "Could not compile script" , ex ) ;
main = type . newInstance ( ) ;
}
catch ( IOException ex ) {
throw new IllegalStateException ( "Could not compile script" , ex ) ;
catch ( Exception ex ) {
// Inner classes and closures will not be instantiatable
return null ;
}
this . mainClass = classes [ 0 ] ;
}
private Class < ? > getMainClass ( ) {
if ( this . mainClass = = null ) {
compile ( ) ;
}
return this . mainClass ;
}
private File locateSource ( String name ) {
String resource = name ;
if ( ! name . endsWith ( ".groovy" ) ) {
resource = "commands/" + name + ".groovy" ;
}
URL url = getClass ( ) . getClassLoader ( ) . getResource ( resource ) ;
if ( url ! = null ) {
return locateSourceFromUrl ( name , url ) ;
}
String home = System . getProperty ( "SPRING_HOME" , System . getenv ( "SPRING_HOME" ) ) ;
if ( home = = null ) {
home = "." ;
}
for ( String path : this . paths ) {
String subbed = path . replace ( "${SPRING_HOME}" , home ) ;
File file = new File ( subbed , resource ) ;
if ( file . exists ( ) ) {
return file ;
}
}
throw new IllegalStateException ( "No script found for : " + name ) ;
}
private File locateSourceFromUrl ( String name , URL url ) {
if ( url . toString ( ) . startsWith ( "file:" ) ) {
return new File ( url . toString ( ) . substring ( "file:" . length ( ) ) ) ;
}
// probably in JAR file
try {
File file = File . createTempFile ( name , ".groovy" ) ;
file . deleteOnExit ( ) ;
FileCopyUtils . copy ( url . openStream ( ) , new FileOutputStream ( file ) ) ;
return file ;
}
catch ( IOException ex ) {
throw new IllegalStateException ( "Could not create temp file for source: "
+ name ) ;
}
}
private static class ScriptConfiguration implements GroovyCompilerConfiguration {
@Override
public GroovyCompilerScope getScope ( ) {
return GroovyCompilerScope . EXTENSION ;
}
@Override
public boolean isGuessImports ( ) {
return true ;
}
@Override
public boolean isAutoconfigure ( ) {
return true ;
}
@Override
public boolean isGuessDependencies ( ) {
return true ;
}
@Override
public String [ ] getClasspath ( ) {
return DEFAULT_CLASSPATH ;
if ( main instanceof Command ) {
return new ScriptCommand ( type . getSimpleName ( ) , main ) ;
}
@Override
public List < RepositoryConfiguration > getRepositoryConfiguration ( ) {
return RepositoryConfigurationFactory . createDefaultRepositoryConfiguration ( ) ;
else if ( main instanceof OptionHandler ) {
( ( OptionHandler ) main ) . options ( ) ;
return new ScriptCommand ( type . getSimpleName ( ) , main ) ;
}
return null ;
}