SHL-66 - Plugins should have access to command line options
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
<config>src/main/resources/META-INF/spring/test.xml</config>
|
||||
<config>src/test/resources/META-INF/spring/spring-shell-plugin.xml</config>
|
||||
</configs>
|
||||
<configSets>
|
||||
</configSets>
|
||||
|
||||
@@ -16,17 +16,13 @@
|
||||
package org.springframework.shell;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.shell.core.CommandMarker;
|
||||
import org.springframework.shell.core.Converter;
|
||||
import org.springframework.shell.core.ExitShellRequest;
|
||||
import org.springframework.shell.core.JLineShellComponent;
|
||||
import org.springframework.shell.core.Shell;
|
||||
@@ -36,8 +32,8 @@ import org.springframework.util.StopWatch;
|
||||
/**
|
||||
* Loads a {@link Shell} using Spring IoC container.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @since 1.0
|
||||
* @author Ben Alex (original Roo code)
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*/
|
||||
public class Bootstrap {
|
||||
@@ -46,21 +42,15 @@ public class Bootstrap {
|
||||
private JLineShellComponent shell;
|
||||
private AnnotationConfigApplicationContext parentApplicationContext;
|
||||
private static StopWatch sw = new StopWatch("Spring Shell");
|
||||
|
||||
//Initialize to empty option to facilitate testing of Bootstrap class
|
||||
private static SimpleShellCommandLineOptions options = new SimpleShellCommandLineOptions();
|
||||
private static CommandLine commandLine;
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
sw.start();
|
||||
options = SimpleShellCommandLineOptions.parseCommandLine(args);
|
||||
|
||||
for (Map.Entry<String, String> entry : options.extraSystemProperties.entrySet()) {
|
||||
System.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
ExitShellRequest exitShellRequest;
|
||||
try {
|
||||
bootstrap = new Bootstrap(null);
|
||||
exitShellRequest = bootstrap.run(options.executeThenQuit);
|
||||
bootstrap = new Bootstrap(args);
|
||||
exitShellRequest = bootstrap.run();
|
||||
} catch (RuntimeException t) {
|
||||
throw t;
|
||||
} finally {
|
||||
@@ -70,8 +60,10 @@ public class Bootstrap {
|
||||
System.exit(exitShellRequest.getExitCode());
|
||||
}
|
||||
|
||||
public Bootstrap(String applicationContextLocation) throws IOException {
|
||||
AnnotationConfigApplicationContext parentApplicationContext = new AnnotationConfigApplicationContext();
|
||||
public Bootstrap(String[] args) throws IOException {
|
||||
commandLine = SimpleShellCommandLineOptions.parseCommandLine(args);
|
||||
|
||||
parentApplicationContext = new AnnotationConfigApplicationContext();
|
||||
configureParentApplicationContext(parentApplicationContext);
|
||||
|
||||
ConfigurableApplicationContext childPluginApplicationContext = createChildPluginApplicationContext(parentApplicationContext);
|
||||
@@ -79,11 +71,10 @@ public class Bootstrap {
|
||||
parentApplicationContext.refresh();
|
||||
childPluginApplicationContext.refresh();
|
||||
|
||||
shell = childPluginApplicationContext.getBean("shell", JLineShellComponent.class);
|
||||
shell.setHistorySize(options.historySize);
|
||||
if (options.executeThenQuit != null) {
|
||||
shell.setPrintBanner(false);
|
||||
}
|
||||
}
|
||||
|
||||
public AnnotationConfigApplicationContext getParentApplicationContext() {
|
||||
return parentApplicationContext;
|
||||
}
|
||||
|
||||
private void configureParentApplicationContext(AnnotationConfigApplicationContext annctx) {
|
||||
@@ -107,7 +98,8 @@ public class Bootstrap {
|
||||
createAndRegisterBeanDefinition(annctx, org.springframework.shell.converters.StaticFieldConverterImpl.class);
|
||||
createAndRegisterBeanDefinition(annctx, org.springframework.shell.core.JLineShellComponent.class, "shell");
|
||||
createAndRegisterBeanDefinition(annctx, org.springframework.shell.converters.SimpleFileConverter.class);
|
||||
|
||||
|
||||
annctx.getBeanFactory().registerSingleton("commandLine", commandLine);
|
||||
annctx.scan("org.springframework.shell.commands");
|
||||
annctx.scan("org.springframework.shell.converters");
|
||||
annctx.scan("org.springframework.shell.plugin.support");
|
||||
@@ -157,15 +149,16 @@ public class Bootstrap {
|
||||
}
|
||||
|
||||
|
||||
protected ExitShellRequest run(String[] executeThenQuit) {
|
||||
protected ExitShellRequest run() {
|
||||
|
||||
String[] commandsToExecuteAndThenQuit = commandLine.getShellCommandsToExecute();
|
||||
ExitShellRequest exitShellRequest;
|
||||
|
||||
if (null != executeThenQuit) {
|
||||
if (null != commandsToExecuteAndThenQuit) {
|
||||
boolean successful = false;
|
||||
exitShellRequest = ExitShellRequest.FATAL_EXIT;
|
||||
|
||||
for (String cmd : executeThenQuit) {
|
||||
for (String cmd : commandsToExecuteAndThenQuit) {
|
||||
successful = shell.executeCommand(cmd);
|
||||
if (!successful)
|
||||
break;
|
||||
|
||||
64
src/main/java/org/springframework/shell/CommandLine.java
Normal file
64
src/main/java/org/springframework/shell/CommandLine.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.shell;
|
||||
|
||||
|
||||
/**
|
||||
* Encapsulates the list of argument passed to the shell.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
public class CommandLine {
|
||||
|
||||
private String[] args;
|
||||
private int historySize;
|
||||
private String[] shellCommandsToExecute;
|
||||
|
||||
/**
|
||||
* Construct a new CommandLine
|
||||
* @param args an array of strings from main(String[] args)
|
||||
* @param historySize the size of this history buffer
|
||||
* @param shellCommandsToExecute semi-colon delimited list of commands for the shell to execute
|
||||
*/
|
||||
public CommandLine(String[] args, int historySize, String[] shellCommandsToExecute) {
|
||||
this.args = args;
|
||||
this.historySize = historySize;
|
||||
this.shellCommandsToExecute = shellCommandsToExecute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the command line arguments
|
||||
* @return the command line arguments
|
||||
*/
|
||||
public String[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the historySize
|
||||
*/
|
||||
public int getHistorySize() {
|
||||
return historySize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the shellCommandsToExecute
|
||||
*/
|
||||
public String[] getShellCommandsToExecute() {
|
||||
return shellCommandsToExecute;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,14 +32,18 @@ import org.springframework.shell.support.logging.HandlerUtils;
|
||||
* @author vnagaraja
|
||||
*/
|
||||
public class SimpleShellCommandLineOptions {
|
||||
|
||||
private static final Logger LOGGER = HandlerUtils.getLogger(SimpleShellCommandLineOptions.class);
|
||||
private static final int DEFAULT_HISTORY_SIZE = 3000;
|
||||
|
||||
private static final Logger LOGGER = HandlerUtils.getLogger(SimpleShellCommandLineOptions.class);
|
||||
public static final int DEFAULT_HISTORY_SIZE = 3000;
|
||||
String[] executeThenQuit = null;
|
||||
Map<String, String> extraSystemProperties = new HashMap<String, String>();
|
||||
int historySize = DEFAULT_HISTORY_SIZE;
|
||||
|
||||
public static SimpleShellCommandLineOptions parseCommandLine(String[] args) throws IOException {
|
||||
public static CommandLine parseCommandLine(String[] args)
|
||||
throws IOException {
|
||||
if (args == null) {
|
||||
args = new String[] {};
|
||||
}
|
||||
SimpleShellCommandLineOptions options = new SimpleShellCommandLineOptions();
|
||||
List<String> commands = new ArrayList<String>();
|
||||
int i = 0;
|
||||
@@ -48,41 +52,37 @@ public class SimpleShellCommandLineOptions {
|
||||
if (arg.equals("--profiles")) {
|
||||
try {
|
||||
String profiles = args[i++];
|
||||
options.extraSystemProperties.put("spring.profiles.active", profiles);
|
||||
options.extraSystemProperties.put("spring.profiles.active", profiles);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
LOGGER.warning("No value specified for --profiles option");
|
||||
}
|
||||
}
|
||||
else if (arg.equals("--cmdfile")) {
|
||||
} else if (arg.equals("--cmdfile")) {
|
||||
try {
|
||||
File f = new File(args[i++]);
|
||||
commands.addAll(FileUtils.readLines(f));
|
||||
commands.addAll(FileUtils.readLines(f));
|
||||
} catch (IOException e) {
|
||||
LOGGER.warning("Could not read lines from command file: " + e.getMessage());
|
||||
LOGGER.warning("Could not read lines from command file: " + e.getMessage());
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
LOGGER.warning("No value specified for --cmdfile option");
|
||||
}
|
||||
}
|
||||
else if (arg.equals("--histsize")) {
|
||||
try {
|
||||
String histSizeArg = args[i++];
|
||||
} else if (arg.equals("--histsize")) {
|
||||
try {
|
||||
String histSizeArg = args[i++];
|
||||
int histSize = Integer.parseInt(histSizeArg);
|
||||
if (histSize <= 0) {
|
||||
LOGGER.warning("histsize option must be > 0, using default value of " + DEFAULT_HISTORY_SIZE);
|
||||
} else {
|
||||
options.historySize = histSize;
|
||||
options.historySize = histSize;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
LOGGER.warning("Unable to parse histsize value to an integer ");
|
||||
LOGGER.warning("Unable to parse histsize value to an integer ");
|
||||
} catch (ArrayIndexOutOfBoundsException ae) {
|
||||
LOGGER.warning("No value specified for --histsize option");
|
||||
}
|
||||
}
|
||||
else if (arg.equals("--help")) {
|
||||
} else if (arg.equals("--help")) {
|
||||
printUsage();
|
||||
System.exit(0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
@@ -99,18 +99,23 @@ public class SimpleShellCommandLineOptions {
|
||||
if (sb.length() > 0) {
|
||||
String[] cmdLineCommands = sb.toString().split(";");
|
||||
for (String s : cmdLineCommands) {
|
||||
//add any command line commands after the commands loaded from the file
|
||||
// add any command line commands after the commands loaded from the file
|
||||
commands.add(s.trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (commands.size() > 0)
|
||||
if (commands.size() > 0) {
|
||||
options.executeThenQuit = commands.toArray(new String[commands.size()]);
|
||||
}
|
||||
|
||||
return options;
|
||||
for (Map.Entry<String, String> entry : options.extraSystemProperties.entrySet()) {
|
||||
System.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return new CommandLine(args, options.historySize, options.executeThenQuit);
|
||||
}
|
||||
|
||||
private static void printUsage(){
|
||||
|
||||
private static void printUsage() {
|
||||
System.out.println("Usage: --help --histsize [size] --cmdfile [file name] --profiles [comma-separated list of profile names]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.context.Lifecycle;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.shell.CommandLine;
|
||||
import org.springframework.shell.plugin.BannerProvider;
|
||||
import org.springframework.shell.plugin.HistoryFileNameProvider;
|
||||
import org.springframework.shell.plugin.PluginProvider;
|
||||
@@ -46,6 +47,9 @@ import org.springframework.shell.plugin.PromptProvider;
|
||||
*/
|
||||
public class JLineShellComponent extends JLineShell implements SmartLifecycle, ApplicationContextAware, InitializingBean {
|
||||
|
||||
@Autowired
|
||||
private CommandLine commandLine;
|
||||
|
||||
private volatile boolean running = false;
|
||||
private Thread shellThread;
|
||||
|
||||
@@ -61,8 +65,6 @@ public class JLineShellComponent extends JLineShell implements SmartLifecycle, A
|
||||
private String version;
|
||||
private String welcomeMessage;
|
||||
|
||||
|
||||
// Fields
|
||||
private ExecutionStrategy executionStrategy = new SimpleExecutionStrategy();
|
||||
private SimpleParser parser = new SimpleParser();
|
||||
|
||||
@@ -114,6 +116,11 @@ public class JLineShellComponent extends JLineShell implements SmartLifecycle, A
|
||||
for (Converter converter : converters.values()) {
|
||||
getSimpleParser().add(converter);
|
||||
}
|
||||
|
||||
setHistorySize(commandLine.getHistorySize());
|
||||
if (commandLine.getShellCommandsToExecute() != null) {
|
||||
setPrintBanner(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +238,7 @@ public class JLineShellComponent extends JLineShell implements SmartLifecycle, A
|
||||
}
|
||||
|
||||
public void printBannerAndWelcome() {
|
||||
if (printBanner) {
|
||||
if (printBanner) {
|
||||
logger.info(this.banner);
|
||||
logger.info(getWelcomeMessage());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.springframework.shell.commands.test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.shell.CommandLine;
|
||||
import org.springframework.shell.core.CommandMarker;
|
||||
import org.springframework.shell.core.annotation.CliCommand;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class OptionsInjectedDummyCommand implements CommandMarker {
|
||||
|
||||
@Autowired
|
||||
private CommandLine commandLine;
|
||||
|
||||
@CliCommand("do nothing")
|
||||
public String simple() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
public CommandLine getCommandLine() {
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.shell.core;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.shell.Bootstrap;
|
||||
import org.springframework.shell.commands.test.OptionsInjectedDummyCommand;
|
||||
import org.springframework.shell.support.logging.HandlerUtils;
|
||||
|
||||
public class CommandLineInjectedTest {
|
||||
|
||||
@Test
|
||||
public void commandLineInjected() throws IOException {
|
||||
try {
|
||||
Bootstrap bootstrap = new Bootstrap(null);
|
||||
AnnotationConfigApplicationContext ctx = bootstrap.getParentApplicationContext();
|
||||
OptionsInjectedDummyCommand dummyCommand = ctx.getBean(OptionsInjectedDummyCommand.class);
|
||||
Assert.assertNotNull("commandLine was not injected into a command", dummyCommand.getCommandLine());
|
||||
} catch (RuntimeException t) {
|
||||
throw t;
|
||||
} finally {
|
||||
HandlerUtils.flushAllHandlers(Logger.getLogger(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/test/resources/META-INF/spring/spring-shell-plugin.xml
Normal file
10
src/test/resources/META-INF/spring/spring-shell-plugin.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
|
||||
|
||||
<context:component-scan base-package="org.springframework.shell.commands.test"/>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user