Skip to content

Commit

Permalink
SHL-66 - Plugins should have access to command line options
Browse files Browse the repository at this point in the history
  • Loading branch information
markpollack committed Dec 19, 2012
1 parent bab23f2 commit 730e33d
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .springBeans
Expand Up @@ -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>
Expand Down
47 changes: 20 additions & 27 deletions src/main/java/org/springframework/shell/Bootstrap.java
Expand Up @@ -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;
Expand All @@ -36,8 +32,8 @@
/**
* 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 {
Expand All @@ -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 {
Expand All @@ -70,20 +60,21 @@ public static void main(String[] args) throws IOException {
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);

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) {
Expand All @@ -107,7 +98,8 @@ private void configureParentApplicationContext(AnnotationConfigApplicationContex
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");
Expand Down Expand Up @@ -157,15 +149,16 @@ private void setupLogging() {
}


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;
Expand Down
64 changes: 64 additions & 0 deletions src/main/java/org/springframework/shell/CommandLine.java
@@ -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;
}

}
Expand Up @@ -32,14 +32,18 @@
* @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;
Expand All @@ -48,41 +52,37 @@ public static SimpleShellCommandLineOptions parseCommandLine(String[] args) thro
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;
}
Expand All @@ -99,18 +99,23 @@ else if (arg.equals("--help")) {
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]");
}
}
Expand Up @@ -33,6 +33,7 @@
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;
Expand All @@ -46,6 +47,9 @@
*/
public class JLineShellComponent extends JLineShell implements SmartLifecycle, ApplicationContextAware, InitializingBean {

@Autowired
private CommandLine commandLine;

private volatile boolean running = false;
private Thread shellThread;

Expand All @@ -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();

Expand Down Expand Up @@ -114,6 +116,11 @@ public void afterPropertiesSet() {
for (Converter converter : converters.values()) {
getSimpleParser().add(converter);
}

setHistorySize(commandLine.getHistorySize());
if (commandLine.getShellCommandsToExecute() != null) {
setPrintBanner(false);
}
}

/**
Expand Down Expand Up @@ -231,7 +238,7 @@ private <T extends PluginProvider> T getHighestPriorityProvider(Class<T> t) {
}

public void printBannerAndWelcome() {
if (printBanner) {
if (printBanner) {
logger.info(this.banner);
logger.info(getWelcomeMessage());
}
Expand Down
@@ -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 comments on commit 730e33d

Please sign in to comment.