SHL-23 - Create docbook based reference guide
This commit is contained in:
BIN
docs/src/reference/docbook/images/shell-example-enum.jpg
Normal file
BIN
docs/src/reference/docbook/images/shell-example-enum.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/src/reference/docbook/images/shell-example.jpg
Normal file
BIN
docs/src/reference/docbook/images/shell-example.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
@@ -16,16 +16,16 @@
|
||||
<surname>Pollack</surname>
|
||||
<affiliation>SpringSource</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Jarred</firstname>
|
||||
<surname>Li</surname>
|
||||
<affiliation>VMware</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Costin</firstname>
|
||||
<surname>Leau</surname>
|
||||
<affiliation>SpringSource</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Jarred</firstname>
|
||||
<surname>Li</surname>
|
||||
<affiliation>VMware</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<legalnotice>
|
||||
@@ -63,7 +63,7 @@
|
||||
<part id="samples">
|
||||
<title>Spring Shell Sample application</title>
|
||||
<xi:include href="samples/introduction.xml"/>
|
||||
<xi:include href="samples/sample-application.xml"/>
|
||||
<xi:include href="samples/simple-application.xml"/>
|
||||
</part>
|
||||
|
||||
</book>
|
||||
@@ -6,7 +6,7 @@
|
||||
xmlns:ns2="http://www.w3.org/1999/xlink"
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<para>The Spring Shell provides an interactive shell that lets you
|
||||
contribute commands using a simple POJO based programming model.</para>
|
||||
contribute commands using a simple Spring based programming model.</para>
|
||||
|
||||
<para>This document is the reference guide for the Spring Shell and covers
|
||||
the key classes that are part of the Shell infrastructure, the plugin model,
|
||||
|
||||
@@ -8,11 +8,7 @@
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<title>Requirements</title>
|
||||
|
||||
<para>The Spring Shell requires JDK level 6.0 (just like Hadoop) and above
|
||||
and the Spring <ulink
|
||||
url="http://www.springsource.org/about">Framework</ulink> 3.0 (3.1
|
||||
recommended) and above.<ulink
|
||||
url="http://www.gemstone.com/products/gemfire"/><ulink
|
||||
url="http://hbase.apache.org/"/><ulink url="http://hive.apache.org/"/><ulink
|
||||
url="http://pig.apache.org/"/></para>
|
||||
<para>The Spring Shell requires JDK level 6.0 and above as well as the
|
||||
Spring <ulink url="http://www.springsource.org/about">Framework</ulink> 3.0
|
||||
(3.1 recommended) and above.</para>
|
||||
</chapter>
|
||||
|
||||
@@ -8,45 +8,40 @@
|
||||
<title>Preface</title>
|
||||
|
||||
<para>The Spring Shell provides an interactive shell that allows you to
|
||||
plugin your own custom commands using a Spring based POJO programming
|
||||
plugin your own custom commands using a Spring based programming
|
||||
model.</para>
|
||||
|
||||
<para>The shell has been extracted from the Spring Roo project, giving it a
|
||||
strong foundation and rich feature set. One significant change from Spring
|
||||
Roo is that the plugin model is no longer based on OSGi but instead uses
|
||||
Spring IoC container to discover commands through classpath scanning. There
|
||||
is currently no classloader isolation between plugins, however that maybe
|
||||
added in future versions.</para>
|
||||
<para>The shell has been extracted from the <link
|
||||
ns2:href="http://www.springsource.org/spring-roo/">Spring Roo
|
||||
project</link>, giving it a strong foundation and rich feature set. One
|
||||
significant change from Spring Roo is that the plugin model is no longer
|
||||
based on OSGi but instead uses Spring IoC container to discover commands
|
||||
through classpath scanning. There is currently no classloader isolation
|
||||
between plugins, however that maybe added in future versions.</para>
|
||||
|
||||
<para>Spring Shell's features include</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>A POJO based programming model to contribute custom
|
||||
commands</para>
|
||||
<para>A simple, annotation driven, programming model to contribute
|
||||
custom commands</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Use Spring's classpath scanning functionality as a basis for a
|
||||
command plugin strategy</para>
|
||||
<para>Use of Spring's classpath scanning functionality asthe basis for a
|
||||
command plugin strategy and command develoment</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Inheritance of the <link
|
||||
ns2:href="http://static.springsource.org/spring-roo/reference/html-single/index.html#usage-shell">Roo
|
||||
Shell features</link></para>
|
||||
Shell features</link>, most notably tab completion, colorization, and
|
||||
script execution.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Tab completion</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Scripting and Script recording</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Customize command prompt, banner, shell history file name.</para>
|
||||
<para>Customizatin of command prompt, banner, shell history file
|
||||
name.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
@@ -10,35 +10,151 @@
|
||||
<title>Developing Spring Shell Applications</title>
|
||||
|
||||
<para>Contributing commands to the shell is very easy. There are only a few
|
||||
annotations you need to learn. The implementation style of the command is in
|
||||
the style of developing an application that uses dependency injection as you
|
||||
can leverage all the features of the Spring container.</para>
|
||||
annotations you need to learn. The implementation style of the command is
|
||||
the same as developing classes in for application that uses dependency
|
||||
injection. You can leverage all the features of the Spring container to
|
||||
implement your command classes.</para>
|
||||
|
||||
<section>
|
||||
<title>Marker Interface</title>
|
||||
|
||||
<para>The first step to creating a command is to implement the market
|
||||
interface CommandMarker and to annotate your class with Spring's
|
||||
@Component annotation. (Note there is an open JIRA issue to provide a
|
||||
@CliCommand meta-annotation to avoid having to use a market interface)
|
||||
Taking the </para>
|
||||
</section>
|
||||
<para>The first step to creating a command is to implement the marker
|
||||
interface <interfacename>CommandMarker</interfacename> and to annotate
|
||||
your class with Spring's <classname>@Component </classname>annotation.
|
||||
(Note there is an open JIRA issue to provide a
|
||||
<classname>@CliCommand</classname> meta-annotation to avoid having to use
|
||||
a marker interface). Using the code from the helloworld sample
|
||||
application, the shell of a <classname>HelloWorldCommands</classname>
|
||||
class is shown below </para>
|
||||
|
||||
<section>
|
||||
<title>CLI Annotations</title>
|
||||
<programlisting>@Component
|
||||
public class HelloWorldCommands implements CommandMarker {
|
||||
|
||||
// use any Spring annotations for Dependency Injection or other Spring interfaces as required.
|
||||
|
||||
<para>annotations</para>
|
||||
// methods with @Cli annotations go here
|
||||
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Logging</title>
|
||||
|
||||
<para/>
|
||||
<para>Logging is done using JDK logging. Simply add a LOG declaration as
|
||||
shown below to use a logger.</para>
|
||||
|
||||
<programlisting>@Component
|
||||
public class HelloWorldCommands implements CommandMarker {
|
||||
|
||||
protected final Logger LOG = Logger.getLogger(getClass().getName());
|
||||
|
||||
// methods with @Cli annotations go here
|
||||
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>CLI Annotations</title>
|
||||
|
||||
<para>There are three annotations used on methods and method arguments
|
||||
that define main contract for interacting with the shell. These are</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><classname>CliAvailabilityIndicator</classname> - Placed on a
|
||||
method that returns a boolean value and indicates if a particular
|
||||
command can be presented in the shell. This decision is usually based
|
||||
on the history of commands that have been executed previously. It
|
||||
prevents extraneous commands being presented until some preconditions
|
||||
are met, for example the execution of a 'configuration'
|
||||
command.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><classname>CliCommand</classname> - Placed on a method that
|
||||
provides a command to the shell. Its value provides one or more
|
||||
strings that serve as the start of a particular command name. These
|
||||
must be unique within the entire application, across all
|
||||
plugins.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><classname>CliOptions</classname> - Placed on the arguments of a
|
||||
command methods, allowing it to declare the argument value as
|
||||
mandatory or optional with a default value.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Here is a simple use of these annotations in a command class </para>
|
||||
|
||||
<programlisting language="java">@Component
|
||||
public class HelloWorldCommands implements CommandMarker {
|
||||
|
||||
protected final Logger LOG = Logger.getLogger(getClass().getName());
|
||||
|
||||
@CliAvailabilityIndicator({"hw simple"})
|
||||
public boolean isCommandAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@CliCommand(value = "hw simple", help = "Print a simple hello world message")
|
||||
public void simple(
|
||||
@CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message,
|
||||
@CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello", specifiedDefaultValue="At work") final String location) {
|
||||
|
||||
LOG.info("Message = [" + message + "] Location = [" + location + "]");
|
||||
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>The method annotated with <classname>@CliAvailabilityIndicator
|
||||
</classname>is returning true so that the one and only command in this
|
||||
class is exposed to the shell to be invoked. If there were more commands
|
||||
in the class, you would list them as comma separated value.</para>
|
||||
|
||||
<para>The <classname>@CliCommand</classname> annotation is creating the
|
||||
command '<literal>hw simple</literal>' in the shell. The help message is
|
||||
what will be printed if you use the build in <literal>help</literal>
|
||||
command. The method name is '<methodname>simple</methodname>' but it could
|
||||
just have well been any other name.</para>
|
||||
|
||||
<para>The <classname>@CliOption</classname> annotation on each of the
|
||||
command arguments is where you will spend most of your time authoring
|
||||
commands. You need to decide which arguments are required, which are
|
||||
optional, and if they are optional is there a default value. In this case
|
||||
there are two arguments or keys to the command, message and location. The
|
||||
key message is required and a help message is provided to give guidance to
|
||||
the user when tabbing to get completion for the command. </para>
|
||||
|
||||
<para>The implementation of the 'simple' method is trivial, just a log
|
||||
statement, but this is where you would typically call other collaborating
|
||||
objects that were injected into the class via Spring.</para>
|
||||
|
||||
<para>The method argument types in this example are
|
||||
<classname>String</classname>, which doesn't present any issue with type
|
||||
conversion. You can specify methods with any rich object type including
|
||||
basic primitive types such as int, float etc. For all types other than
|
||||
those handled by the shell by default (basic types,
|
||||
<classname>Date</classname>, <classname>File</classname>) you will need to
|
||||
register your own implementation of the
|
||||
<interfacename>org.springframework.shell.core.Converter</interfacename>
|
||||
interface with the container in your plugin.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Building and running the shell</title>
|
||||
|
||||
<para/>
|
||||
<para>In our opinion, the easiest way to build an execute the shell is to
|
||||
cut-n-paste the gradle script in the example application. This uses the
|
||||
application plugin from gradle to create a bin directory with a startup
|
||||
script for windows and Unix and places all dependent jars in a lib
|
||||
directory. Maven has a similar plugin - the <link
|
||||
xlink:href="http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/">AppAssembler</link>
|
||||
plugin.</para>
|
||||
|
||||
<para>The main class of the shell is
|
||||
<classname>org.springframework.shell.Bootstrap</classname>. As long as you
|
||||
place other plugins, perhaps developed independently, on the classpath,
|
||||
the Bootstrap class will incorporate them into the shell.</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
looks like this<programlisting>new ClassPathXmlApplicationContext("classpath*:/META-INF/spring/spring-shell-plugin.xml");</programlisting></para>
|
||||
|
||||
<para>In the <literal>spring-shell-plugin.xml</literal> file you should
|
||||
define the command classes and any other collaboration objects that
|
||||
support the commands actions. The plugin model is depicted in the
|
||||
define the command classes and any other collaborating objects that
|
||||
support the command's actions. The plugin model is depicted in the
|
||||
following diagram</para>
|
||||
|
||||
<mediaobject>
|
||||
@@ -41,7 +41,7 @@
|
||||
<title>Commands</title>
|
||||
|
||||
<para>An easy way to declare the commands is to use Spring's component
|
||||
scanning functionality.Here is an example
|
||||
scanning functionality. Here is an example
|
||||
<literal>spring-shell-plugin.xml </literal>that from the sample
|
||||
application.</para>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
</beans></programlisting>
|
||||
|
||||
<para>The commands are Spring components, demarcated as such using the
|
||||
<literal>@Component</literal> annotation. For example, the
|
||||
<literal>@Component</literal> annotation. For example, the shell of the
|
||||
<classname>HelloWorldCommands</classname> class from the sample
|
||||
application looks like this</para>
|
||||
|
||||
@@ -82,7 +82,7 @@ public class HelloWorldCommands implements CommandMarker {
|
||||
<para>The
|
||||
<interfacename>org.springframework.shell.core.Converter</interfacename>
|
||||
interface provides the contract to convert the strings that are entered
|
||||
in the command to rich Java types passed into the arguments of
|
||||
on the command line to rich Java types passed into the arguments of
|
||||
<classname>@Cli</classname>-annotated methods.</para>
|
||||
|
||||
<para>By default converters for common types are registered. These cover
|
||||
@@ -122,6 +122,30 @@ public class HelloWorldCommands implements CommandMarker {
|
||||
executed.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>There are also a few commands that are provided by the
|
||||
<classname>AbstractShell</classname> class, these are</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>date</literal> - Displays the local date and
|
||||
time</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>script</literal> - Parses the specified resource file
|
||||
and executes its commands</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>system properties</literal> - Shows the shell's
|
||||
properties</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>version</literal> - Displays current CLI version</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -133,13 +157,14 @@ public class HelloWorldCommands implements CommandMarker {
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><interfacename>BannerProvider</interfacename> - Specifies the
|
||||
banner text , welcome message, and version number that will be
|
||||
banner text, welcome message, and version number that will be
|
||||
displayed when the shell is started</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><interfacename>PromptProvider</interfacename> - Specifies the
|
||||
command prompt text</para>
|
||||
command prompt text, eg. "<literal>shell></literal>" or
|
||||
"<literal>#</literal>" or "<literal>$</literal>"</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
@@ -176,10 +201,10 @@ public class HelloWorldCommands implements CommandMarker {
|
||||
<para>It has shown to be useful to provide a simple form of interception
|
||||
around the invocation of a command method. This enables the command class
|
||||
to check for updates to state, such as configuration information modified
|
||||
by other plugins, before the command is executed. The interface
|
||||
by other plugins, before the command method is executed. The interface
|
||||
<interfacename>ExecutionProcess</interfacename> should be implemented
|
||||
instead of <interfacename>CommandMarker</interfacename> to access this
|
||||
functionlatiy. The <interfacename>ExecutionProcess</interfacename>
|
||||
functionality. The <interfacename>ExecutionProcess</interfacename>
|
||||
interface is shown below</para>
|
||||
|
||||
<programlisting>public interface ExecutionProcessor extends CommandMarker {
|
||||
@@ -212,4 +237,43 @@ public class HelloWorldCommands implements CommandMarker {
|
||||
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Command line options</title>
|
||||
|
||||
<para>There are a few command line options that can be specified when
|
||||
starting the shell. They are </para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>--profiles</literal> - Specifies values for the system
|
||||
property spring.profiles.active so that Spring 3.1 and greater <link
|
||||
xlink:href="http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/">profile
|
||||
support </link>is enabled.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>--cmdfile</literal> - Specifies a file to read that
|
||||
contains shell commands</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>--histsize</literal> - Specifies the maximum number of
|
||||
lines to store in the command history file. Default value is
|
||||
3000.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Scripts and comments</title>
|
||||
|
||||
<para>Scripts can be executed either by passing in the
|
||||
<literal>--cmdfile</literal> argument at startup or by executing the
|
||||
<literal>script</literal> command inside the shell. When using scripts it
|
||||
helps to add comments and this can be done using block comments that start
|
||||
and end with <literal>/*</literal> and <literal>*/</literal> or an inline
|
||||
one line command using <literal>//</literal> or <literal>;</literal>
|
||||
characters.</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter version="5.0" xml:id="simple-application" xmlns="http://docbook.org/ns/docbook"
|
||||
<chapter version="5.0" xml:id="simple-application"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:ns5="http://www.w3.org/1998/Math/MathML"
|
||||
@@ -8,12 +9,127 @@
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<title>Simple sample application using the Spring Shell</title>
|
||||
|
||||
<section id="shell:simple-application">
|
||||
<section>
|
||||
<title>Introduction</title>
|
||||
|
||||
This sample demonstrates how to execute a MapReduce application and a script that interacts with HDFS inside a Spring based application. It does not use spring Batch or Spring Integration.
|
||||
<para>The sample application named 'helloworld' contains three
|
||||
'<literal>hw</literal>' commands, they are '<literal>hw simple</literal>',
|
||||
'<literal>hw complex</literal>' and '<literal>hw enum</literal>' and
|
||||
demonstrate simple to intermediate level usage of the
|
||||
<literal>@Cli</literal> annotation classes for creating commands.</para>
|
||||
|
||||
<para>The example code is located in the distribution directory
|
||||
<literal><spring-hadoop-install-dir>/samples/wordcount</literal>.</para>
|
||||
<literal><spring-shell-install-dir>/samples/helloworld</literal>.</para>
|
||||
|
||||
<para>To build the example cd to the helloworld directory and execute
|
||||
<literal>..\..\gradlew installApp</literal>. To run the application cd to
|
||||
<literal>build\install\helloworld\bin</literal> and execute the helloworld
|
||||
script.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>HelloWorldCommands</title>
|
||||
|
||||
<para>The <classname>HelloWorldCommands</classname> class is show
|
||||
below</para>
|
||||
|
||||
<programlisting language="java">package org.springframework.shell.samples.helloworld.commands;
|
||||
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.springframework.shell.core.CommandMarker;
|
||||
import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
|
||||
import org.springframework.shell.core.annotation.CliCommand;
|
||||
import org.springframework.shell.core.annotation.CliOption;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class HelloWorldCommands implements CommandMarker {
|
||||
|
||||
protected final Logger LOG = Logger.getLogger(getClass().getName());
|
||||
|
||||
private boolean simpleCommandExecuted = false;
|
||||
|
||||
@CliAvailabilityIndicator({"hw simple"})
|
||||
public boolean isSimpleAvailable() {
|
||||
//always available
|
||||
return true;
|
||||
}
|
||||
|
||||
@CliAvailabilityIndicator({"hw complex", "hw enum"})
|
||||
public boolean isComplexAvailable() {
|
||||
if (simpleCommandExecuted) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@CliCommand(value = "hw simple", help = "Print a simple hello world message")
|
||||
public void simple(
|
||||
@CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message,
|
||||
@CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello", specifiedDefaultValue="At work") final String location) {
|
||||
LOG.info("Message = [" + message + "] Location = [" + location + "]");
|
||||
simpleCommandExecuted = true;
|
||||
}
|
||||
|
||||
@CliCommand(value = "hw complex", help = "Print a complex hello world message")
|
||||
public void hello(
|
||||
@CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message,
|
||||
@CliOption(key = { "name1"}, mandatory = true, help = "Say hello to the first name") final String name1,
|
||||
@CliOption(key = { "name2" }, mandatory = true, help = "Say hello to a second name") final String name2,
|
||||
@CliOption(key = { "time" }, mandatory = false, specifiedDefaultValue="now", help = "When you are saying hello") final String time,
|
||||
@CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello") final String location) {
|
||||
LOG.info("Hello " + name1 + " and " + name2 + ". Your special message is " + message + ". time=[" + time + "] location=[" + location + "]");
|
||||
}
|
||||
|
||||
@CliCommand(value = "hw enum", help = "Print a simple hello world message from an enumerated value")
|
||||
public void eenum(
|
||||
@CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final MessageType message){
|
||||
LOG.info("Hello. You special enumerated message is " + message);
|
||||
}
|
||||
|
||||
enum MessageType {
|
||||
Type1("type1"),
|
||||
Type2("type2"),
|
||||
Type3("type3");
|
||||
|
||||
private String type;
|
||||
|
||||
private MessageType(String type){
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType(){
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>The use of the <classname>@CliAvailabilityIndicator</classname>
|
||||
annotation on two methods, <methodname>isSimpleAvailable</methodname> and
|
||||
<methodname>isComplexAvailable</methodname> shows how you can enable the
|
||||
presence of the '<literal>hw complex</literal>' and '<literal>hw
|
||||
enum</literal>' commands only if the '<literal>hw simple</literal>'
|
||||
command was executed.</para>
|
||||
|
||||
<para>Here is an example session showing the behavior.</para>
|
||||
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="../images/shell-example.jpg"/>
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
|
||||
<para>The '<literal>hw enum</literal>' command shows how the shell
|
||||
supports the use of Enumeration as command method arguments.</para>
|
||||
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="../images/shell-example-enum.jpg"/>
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
2
samples/helloworld/.gitignore
vendored
2
samples/helloworld/.gitignore
vendored
@@ -5,4 +5,4 @@ target/
|
||||
/log.roo
|
||||
*.log
|
||||
|
||||
|
||||
/bin/
|
||||
|
||||
@@ -11,15 +11,34 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class HelloWorldCommands implements CommandMarker {
|
||||
|
||||
|
||||
protected final Logger LOG = Logger.getLogger(getClass().getName());
|
||||
|
||||
@CliAvailabilityIndicator({"hw echo"})
|
||||
public boolean isCommandAvailable() {
|
||||
private boolean simpleCommandExecuted = false;
|
||||
|
||||
@CliAvailabilityIndicator({"hw simple"})
|
||||
public boolean isSimpleAvailable() {
|
||||
//always available
|
||||
return true;
|
||||
}
|
||||
|
||||
@CliAvailabilityIndicator({"hw complex", "hw enum"})
|
||||
public boolean isComplexCommandAvailable() {
|
||||
if (simpleCommandExecuted) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@CliCommand(value = "hw simple", help = "Print a simple hello world message")
|
||||
public void simple(
|
||||
@CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message,
|
||||
@CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello", specifiedDefaultValue="At work") final String location) {
|
||||
LOG.info("Message = [" + message + "] Location = [" + location + "]");
|
||||
simpleCommandExecuted = true;
|
||||
}
|
||||
|
||||
@CliCommand(value = "hw complex", help = "Print a complex hello world message")
|
||||
public void hello(
|
||||
@CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message,
|
||||
|
||||
@@ -20,6 +20,14 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* Annotates a method that provides a command to the shell.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface CliCommand {
|
||||
|
||||
@@ -22,7 +22,13 @@ import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.shell.core.Converter;
|
||||
|
||||
|
||||
/**
|
||||
* Annotates the arguments of a command methods, allowing it to declare the argument value as mandatory or optional with a default value.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.PARAMETER)
|
||||
public @interface CliOption {
|
||||
|
||||
Reference in New Issue
Block a user