diff --git a/gradle.properties b/gradle.properties
index dd9b71dc..e53150ef 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -18,4 +18,4 @@ mockitoVersion = 1.8.5
# --------------------
# Project wide version
# --------------------
-version=1.0.1.BUILD-SNAPSHOT
\ No newline at end of file
+version=1.1.0.BUILD-SNAPSHOT
diff --git a/samples/helloworld/gradle.properties b/samples/helloworld/gradle.properties
index 02cfd69b..6d9730c7 100644
--- a/samples/helloworld/gradle.properties
+++ b/samples/helloworld/gradle.properties
@@ -1,4 +1,4 @@
-springShellVersion = 1.0.1.BUILD-SNAPSHOT
+springShellVersion = 1.1.0.BUILD-SNAPSHOT
log4jVersion = 1.2.17
version = 1.0.0.RELEASE
diff --git a/samples/helloworld/pom.xml b/samples/helloworld/pom.xml
index 7f6a5df0..bc0880cf 100644
--- a/samples/helloworld/pom.xml
+++ b/samples/helloworld/pom.xml
@@ -11,7 +11,7 @@
http://maven.apache.org
- 1.0.0.RELEASE
+ 1.1.0.BUILD-SNAPSHOT
org.springframework.shell.Bootstrap
1.2.17
diff --git a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/Main.java b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/Main.java
new file mode 100644
index 00000000..1ce398e3
--- /dev/null
+++ b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/Main.java
@@ -0,0 +1,40 @@
+/*
+ * 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.samples.helloworld;
+
+import java.io.IOException;
+
+import org.springframework.shell.Bootstrap;
+
+/**
+ * Driver class to run the helloworld example.
+ *
+ * @author Mark Pollack
+ *
+ */
+public class Main {
+
+ /**
+ * Main class that delegates to Spring Shell's Bootstrap class in order to simplify debugging inside an IDE
+ * @param args
+ * @throws IOException
+ */
+ public static void main(String[] args) throws IOException {
+ Bootstrap.main(args);
+
+ }
+
+}
diff --git a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyBannerProvider.java b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyBannerProvider.java
index 96cb19b8..32481e2a 100644
--- a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyBannerProvider.java
+++ b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyBannerProvider.java
@@ -54,7 +54,7 @@ public class MyBannerProvider extends DefaultBannerProvider
}
@Override
- public String name() {
- return "helloworld";
+ public String getProviderName() {
+ return "Hello World Banner";
}
}
\ No newline at end of file
diff --git a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyHistoryFileNameProvider.java b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyHistoryFileNameProvider.java
index 33b309b0..77c745c4 100644
--- a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyHistoryFileNameProvider.java
+++ b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyHistoryFileNameProvider.java
@@ -28,15 +28,15 @@ import org.springframework.stereotype.Component;
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
-public class MyHistoryFileNameProvider extends DefaultHistoryFileNameProvider{
+public class MyHistoryFileNameProvider extends DefaultHistoryFileNameProvider {
public String getHistoryFileName() {
return "my.log";
}
@Override
- public String name() {
- return "my history file name provider";
+ public String getProviderName() {
+ return "My history file name provider";
}
}
diff --git a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyPromptProvider.java b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyPromptProvider.java
index 469da31c..ba875c27 100644
--- a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyPromptProvider.java
+++ b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyPromptProvider.java
@@ -35,8 +35,8 @@ public class MyPromptProvider extends DefaultPromptProvider {
@Override
- public String name() {
- return "my prompt provider";
+ public String getProviderName() {
+ return "My prompt provider";
}
}
diff --git a/samples/helloworld/src/main/resources/META-INF/spring/spring-shell-plugin.xml b/samples/helloworld/src/main/resources/META-INF/spring/spring-shell-plugin.xml
index c8d367a0..9c76b239 100644
--- a/samples/helloworld/src/main/resources/META-INF/spring/spring-shell-plugin.xml
+++ b/samples/helloworld/src/main/resources/META-INF/spring/spring-shell-plugin.xml
@@ -3,7 +3,7 @@
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">
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
diff --git a/src/main/java/org/springframework/shell/Bootstrap.java b/src/main/java/org/springframework/shell/Bootstrap.java
index 841e61e3..59df1695 100644
--- a/src/main/java/org/springframework/shell/Bootstrap.java
+++ b/src/main/java/org/springframework/shell/Bootstrap.java
@@ -19,10 +19,13 @@ import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
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.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
+import org.springframework.context.support.GenericApplicationContext;
import org.springframework.shell.core.ExitShellRequest;
import org.springframework.shell.core.JLineShellComponent;
import org.springframework.shell.core.Shell;
@@ -38,10 +41,13 @@ import org.springframework.util.StopWatch;
*/
public class Bootstrap {
+ private final static String[] CONTEXT_PATH = { "classpath*:/META-INF/spring/spring-shell-plugin.xml" };
+
private static Bootstrap bootstrap;
- private AnnotationConfigApplicationContext parentApplicationContext;
private static StopWatch sw = new StopWatch("Spring Shell");
private static CommandLine commandLine;
+
+ private GenericApplicationContext ctx;
public static void main(String[] args) throws IOException {
@@ -60,25 +66,34 @@ public class Bootstrap {
}
public Bootstrap(String[] args) throws IOException {
- commandLine = SimpleShellCommandLineOptions.parseCommandLine(args);
-
- parentApplicationContext = new AnnotationConfigApplicationContext();
- configureParentApplicationContext(parentApplicationContext);
-
- ConfigurableApplicationContext childPluginApplicationContext = createChildPluginApplicationContext(parentApplicationContext);
-
- parentApplicationContext.refresh();
- childPluginApplicationContext.refresh();
-
+ this(args, CONTEXT_PATH);
}
- public AnnotationConfigApplicationContext getParentApplicationContext() {
- return parentApplicationContext;
+ public Bootstrap(String[] args, String[] contextPath) {
+ try {
+ commandLine = SimpleShellCommandLineOptions.parseCommandLine(args);
+ } catch (IOException e) {
+ throw new ShellException(e.getMessage(), e);
+ }
+
+ ctx = new GenericApplicationContext();
+ ctx.registerShutdownHook();
+ configureApplicationContext(ctx);
+ //built-in commands and converters
+ ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(ctx);
+ scanner.scan("org.springframework.shell.commands", "org.springframework.shell.converters", "org.springframework.shell.plugin.support");
+ //user contributed commands
+ XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) ctx);
+ reader.loadBeanDefinitions(contextPath);
+ ctx.refresh();
+ }
+
+
+ public ApplicationContext getApplicationContext() {
+ return ctx;
}
- private void configureParentApplicationContext(AnnotationConfigApplicationContext annctx) {
- // create parent/base childPluginApplicationContext
-
+ private void configureApplicationContext(GenericApplicationContext annctx) {
createAndRegisterBeanDefinition(annctx, org.springframework.shell.converters.StringConverter.class);
createAndRegisterBeanDefinition(annctx,
org.springframework.shell.converters.AvailableCommandsConverter.class);
@@ -99,35 +114,21 @@ public class Bootstrap {
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");
-
}
- /**
- * Init plugin ApplicationContext
- *
- * @param annctx parent ApplicationContext in core spring shell
- * @return new ApplicationContext in the plugin with core spring shell's context as parent
- */
- private ConfigurableApplicationContext createChildPluginApplicationContext(AnnotationConfigApplicationContext annctx) {
- return new ClassPathXmlApplicationContext(
- new String[] { "classpath*:/META-INF/spring/spring-shell-plugin.xml" }, false, annctx);
- }
-
- protected void createAndRegisterBeanDefinition(AnnotationConfigApplicationContext annctx, Class clazz) {
+ protected void createAndRegisterBeanDefinition(GenericApplicationContext annctx, Class clazz) {
createAndRegisterBeanDefinition(annctx, clazz, null);
}
- protected void createAndRegisterBeanDefinition(AnnotationConfigApplicationContext annctx, Class clazz, String name) {
+ protected void createAndRegisterBeanDefinition(GenericApplicationContext annctx, Class clazz, String name) {
RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setBeanClass(clazz);
+ DefaultListableBeanFactory bf = (DefaultListableBeanFactory)annctx.getBeanFactory();
if (name != null) {
- annctx.registerBeanDefinition(name, rbd);
+ bf.registerBeanDefinition(name, rbd);
}
else {
- annctx.registerBeanDefinition(clazz.getSimpleName(), rbd);
+ bf.registerBeanDefinition(clazz.getSimpleName(), rbd);
}
}
@@ -152,7 +153,7 @@ public class Bootstrap {
String[] commandsToExecuteAndThenQuit = commandLine.getShellCommandsToExecute();
// The shell is used
- JLineShellComponent shell = parentApplicationContext.getBean("shell", JLineShellComponent.class);
+ JLineShellComponent shell = ctx.getBean("shell", JLineShellComponent.class);
ExitShellRequest exitShellRequest;
if (null != commandsToExecuteAndThenQuit) {
@@ -181,7 +182,7 @@ public class Bootstrap {
shell.waitForComplete();
}
- parentApplicationContext.close();
+ ctx.close();
sw.stop();
if (shell.isDevelopmentMode()) {
System.out.println("Total execution time: " + sw.getLastTaskTimeMillis() + " ms");
@@ -190,6 +191,6 @@ public class Bootstrap {
}
JLineShellComponent getJLineShellComponent() {
- return parentApplicationContext.getBean("shell", JLineShellComponent.class);
+ return ctx.getBean("shell", JLineShellComponent.class);
}
}
\ No newline at end of file
diff --git a/src/main/java/org/springframework/shell/ShellException.java b/src/main/java/org/springframework/shell/ShellException.java
new file mode 100644
index 00000000..3caa04d9
--- /dev/null
+++ b/src/main/java/org/springframework/shell/ShellException.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011-2013 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;
+
+
+/**
+ * Shell exception.
+ *
+ * @author David Wintefeldt
+ */
+public class ShellException extends RuntimeException {
+
+ private static final long serialVersionUID = 1123895874463364743L;
+
+ public ShellException() {}
+
+ public ShellException(String message) {
+ super(message);
+ }
+
+ public ShellException(Throwable t) {
+ super(t);
+ }
+
+ public ShellException(String message, Throwable t) {
+ super(message, t);
+ }
+
+}
diff --git a/src/main/java/org/springframework/shell/core/JLineShellComponent.java b/src/main/java/org/springframework/shell/core/JLineShellComponent.java
index c06821ca..f3107bb4 100644
--- a/src/main/java/org/springframework/shell/core/JLineShellComponent.java
+++ b/src/main/java/org/springframework/shell/core/JLineShellComponent.java
@@ -22,6 +22,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
@@ -36,8 +38,9 @@ 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;
+import org.springframework.shell.plugin.NamedProvider;
import org.springframework.shell.plugin.PromptProvider;
+import org.springframework.shell.support.logging.HandlerUtils;
/**
* Launcher for {@link JLineShell}.
@@ -187,7 +190,9 @@ public class JLineShellComponent extends JLineShell implements SmartLifecycle, A
* @return history file name
*/
protected String getHistoryFileName() {
- String providerHistoryFileName = getHighestPriorityProvider(HistoryFileNameProvider.class).getHistoryFileName();
+ HistoryFileNameProvider historyFileNameProvider = getHighestPriorityProvider(HistoryFileNameProvider.class);
+ this.logger.log(Level.FINE, "Using HistoryFileName Provider Class " + historyFileNameProvider.getClass());
+ String providerHistoryFileName = historyFileNameProvider.getHistoryFileName();
if (providerHistoryFileName != null) {
return providerHistoryFileName;
} else {
@@ -202,7 +207,9 @@ public class JLineShellComponent extends JLineShell implements SmartLifecycle, A
* @return prompt text
*/
protected String getPromptText() {
- String providerPromptText = getHighestPriorityProvider(PromptProvider.class).getPrompt();
+ PromptProvider promptProvider = getHighestPriorityProvider(PromptProvider.class);
+ this.logger.log(Level.FINE, "Using Prompt Provider Class " + promptProvider.getClass());
+ String providerPromptText = promptProvider.getPrompt();
if (providerPromptText != null) {
return providerPromptText;
} else {
@@ -221,15 +228,16 @@ public class JLineShellComponent extends JLineShell implements SmartLifecycle, A
private String[] getBannerText() {
String[] bannerText = new String[4];
BannerProvider provider = getHighestPriorityProvider(BannerProvider.class);
+ this.logger.log(Level.FINE, "Using BannerProvider class " + provider.getClass());
bannerText[0] = provider.getBanner();
bannerText[1] = provider.getWelcomeMessage();
bannerText[2] = provider.getVersion();
- bannerText[3] = provider.name();
+ bannerText[3] = provider.getProviderName();
return bannerText;
}
- private T getHighestPriorityProvider(Class t) {
+ private T getHighestPriorityProvider(Class t) {
Map providers = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, t);
List sortedProviders = new ArrayList(providers.values());
Collections.sort(sortedProviders, annotationOrderComparator);
diff --git a/src/main/java/org/springframework/shell/plugin/BannerProvider.java b/src/main/java/org/springframework/shell/plugin/BannerProvider.java
index 39d17248..16f1150c 100644
--- a/src/main/java/org/springframework/shell/plugin/BannerProvider.java
+++ b/src/main/java/org/springframework/shell/plugin/BannerProvider.java
@@ -26,7 +26,7 @@ package org.springframework.shell.plugin;
* @since 1.0
*
*/
-public interface BannerProvider extends PluginProvider {
+public interface BannerProvider extends NamedProvider {
/**
* Returns the banner.
diff --git a/src/main/java/org/springframework/shell/plugin/HistoryFileNameProvider.java b/src/main/java/org/springframework/shell/plugin/HistoryFileNameProvider.java
index f7670c5e..f26b41ca 100644
--- a/src/main/java/org/springframework/shell/plugin/HistoryFileNameProvider.java
+++ b/src/main/java/org/springframework/shell/plugin/HistoryFileNameProvider.java
@@ -25,7 +25,7 @@ package org.springframework.shell.plugin;
* @since 1.0
*
*/
-public interface HistoryFileNameProvider extends PluginProvider {
+public interface HistoryFileNameProvider extends NamedProvider {
/**
* get history file name
diff --git a/src/main/java/org/springframework/shell/plugin/PluginProvider.java b/src/main/java/org/springframework/shell/plugin/NamedProvider.java
similarity index 68%
rename from src/main/java/org/springframework/shell/plugin/PluginProvider.java
rename to src/main/java/org/springframework/shell/plugin/NamedProvider.java
index 3d36e2f7..490f372b 100644
--- a/src/main/java/org/springframework/shell/plugin/PluginProvider.java
+++ b/src/main/java/org/springframework/shell/plugin/NamedProvider.java
@@ -16,16 +16,19 @@
package org.springframework.shell.plugin;
/**
- * Generic plugin provider.
+ * Returns the name of the provider. Providers customize features of the shell such as the banner and command line prompt.
+ *
*
* @author Jarred Li
+ * @author Mark Pollack
+ * @see BannerProvider
+ * @see PromptProvider
+ * @see HistoryFileNameProvider
*/
-public interface PluginProvider {
+public interface NamedProvider {
/**
- * Returns the name of the plugin.
- *
- * @return
+ * Return the name of the provider.
*/
- String name();
+ String getProviderName();
}
diff --git a/src/main/java/org/springframework/shell/plugin/PromptProvider.java b/src/main/java/org/springframework/shell/plugin/PromptProvider.java
index 9c000d5d..70721e5c 100644
--- a/src/main/java/org/springframework/shell/plugin/PromptProvider.java
+++ b/src/main/java/org/springframework/shell/plugin/PromptProvider.java
@@ -24,7 +24,7 @@ package org.springframework.shell.plugin;
* @author Jarred Li
*
*/
-public interface PromptProvider extends PluginProvider {
+public interface PromptProvider extends NamedProvider {
/**
* Returns the prompt text.
diff --git a/src/main/java/org/springframework/shell/plugin/support/DefaultBannerProvider.java b/src/main/java/org/springframework/shell/plugin/support/DefaultBannerProvider.java
index 0b063d32..df951fea 100644
--- a/src/main/java/org/springframework/shell/plugin/support/DefaultBannerProvider.java
+++ b/src/main/java/org/springframework/shell/plugin/support/DefaultBannerProvider.java
@@ -48,10 +48,10 @@ public class DefaultBannerProvider implements BannerProvider {
}
public String getWelcomeMessage() {
- return "Welcome to " + name() + ". For assistance press or type \"hint\" then hit ENTER.";
+ return "Welcome to " + getProviderName() + ". For assistance press or type \"hint\" then hit ENTER.";
}
- public String name() {
+ public String getProviderName() {
return "Spring Shell";
}
}
\ No newline at end of file
diff --git a/src/main/java/org/springframework/shell/plugin/support/DefaultHistoryFileNameProvider.java b/src/main/java/org/springframework/shell/plugin/support/DefaultHistoryFileNameProvider.java
index 74ab23ac..3518cba1 100644
--- a/src/main/java/org/springframework/shell/plugin/support/DefaultHistoryFileNameProvider.java
+++ b/src/main/java/org/springframework/shell/plugin/support/DefaultHistoryFileNameProvider.java
@@ -34,7 +34,7 @@ public class DefaultHistoryFileNameProvider implements HistoryFileNameProvider {
return "spring-shell.log";
}
- public String name() {
+ public String getProviderName() {
return "default history provider";
}
}
diff --git a/src/main/java/org/springframework/shell/plugin/support/DefaultPromptProvider.java b/src/main/java/org/springframework/shell/plugin/support/DefaultPromptProvider.java
index 922de503..26451239 100644
--- a/src/main/java/org/springframework/shell/plugin/support/DefaultPromptProvider.java
+++ b/src/main/java/org/springframework/shell/plugin/support/DefaultPromptProvider.java
@@ -34,7 +34,7 @@ public class DefaultPromptProvider implements PromptProvider {
return "spring-shell>";
}
- public String name() {
+ public String getProviderName() {
return "default prompt provider";
}
}
diff --git a/src/test/java/org/springframework/shell/core/CommandLineInjectedTest.java b/src/test/java/org/springframework/shell/core/CommandLineInjectedTest.java
index c8663a84..62b91bf4 100644
--- a/src/test/java/org/springframework/shell/core/CommandLineInjectedTest.java
+++ b/src/test/java/org/springframework/shell/core/CommandLineInjectedTest.java
@@ -22,7 +22,7 @@ import java.util.logging.Logger;
import junit.framework.Assert;
import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.ApplicationContext;
import org.springframework.shell.Bootstrap;
import org.springframework.shell.commands.test.OptionsInjectedDummyCommand;
import org.springframework.shell.support.logging.HandlerUtils;
@@ -33,7 +33,7 @@ public class CommandLineInjectedTest {
public void commandLineInjected() throws IOException {
try {
Bootstrap bootstrap = new Bootstrap(null);
- AnnotationConfigApplicationContext ctx = bootstrap.getParentApplicationContext();
+ ApplicationContext ctx = bootstrap.getApplicationContext();
OptionsInjectedDummyCommand dummyCommand = ctx.getBean(OptionsInjectedDummyCommand.class);
Assert.assertNotNull("commandLine was not injected into a command", dummyCommand.getCommandLine());
} catch (RuntimeException t) {