diff --git a/README.adoc b/README.adoc index 85f4e8f28..65af68490 100644 --- a/README.adoc +++ b/README.adoc @@ -20,14 +20,13 @@ Here is a quick teaser of a complete Spring Shell application in Java: ---- import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.shell.standard.ShellComponent; -import org.springframework.shell.standard.ShellMethod; +import org.springframework.shell.command.annotation.Command; @SpringBootApplication -@ShellComponent +@Command public class DemoApplication { - @ShellMethod + @Command public String hi() { return "hi"; } diff --git a/spring-shell-docs/modules/ROOT/pages/commands/exceptionhandling/annotation.adoc b/spring-shell-docs/modules/ROOT/pages/commands/exceptionhandling/annotation.adoc index e3cef0069..e8373f01b 100644 --- a/spring-shell-docs/modules/ROOT/pages/commands/exceptionhandling/annotation.adoc +++ b/spring-shell-docs/modules/ROOT/pages/commands/exceptionhandling/annotation.adoc @@ -3,7 +3,7 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs] -`@ShellComponent` classes can have `@ExceptionResolver` methods to handle exceptions from component +`@Command` classes can have `@ExceptionResolver` methods to handle exceptions from component methods. These are meant for annotated methods. The exception may match against a top-level exception being propagated (e.g. a direct `IOException` diff --git a/spring-shell-docs/modules/ROOT/pages/commands/interactionmode.adoc b/spring-shell-docs/modules/ROOT/pages/commands/interactionmode.adoc index 1ea32f2e9..f8db122ea 100644 --- a/spring-shell-docs/modules/ROOT/pages/commands/interactionmode.adoc +++ b/spring-shell-docs/modules/ROOT/pages/commands/interactionmode.adoc @@ -14,7 +14,7 @@ You can define the interaction mode with `CommandRegisration`: include::{snippets}/CommandRegistrationInteractionModeSnippets.java[tag=snippet1] ---- -Or with `@ShellMethod`. +Or with `@Command`. [source, java, indent=0] ---- diff --git a/spring-shell-docs/modules/ROOT/pages/commands/organize.adoc b/spring-shell-docs/modules/ROOT/pages/commands/organize.adoc index 8a275adb7..c90d4167e 100644 --- a/spring-shell-docs/modules/ROOT/pages/commands/organize.adoc +++ b/spring-shell-docs/modules/ROOT/pages/commands/organize.adoc @@ -10,42 +10,36 @@ To alleviate this possible confusion, Spring Shell provides the ability to group with reasonable defaults. Related commands would then end up in the same group (for example, `User Management Commands`) and be displayed together in the help screen and other places. -By default, commands are grouped according to the class they are implemented in, -turning the camelCase class name into separate words (so `URLRelatedCommands` becomes `URL Related Commands`). -This is a sensible default, as related commands are often already in the class anyway, -because they need to use the same collaborating objects. +By default, commands are grouped into the `Default` group. However, you can override the group for +a command in the following ways, in order of priority: -If, however, this behavior does not suit you, you can override the group for a -command in the following ways, in order of priority: +. Specify a `group()` in the `@Command` annotation on the method. -. Specify a `group()` in the `@ShellMethod` annotation. -. Place a `@ShellCommandGroup` on the class in which the command is defined. This applies +. Specify a `group()` in the `@Command` annotation on the class in which the command is defined. This applies the group for all commands defined in that class (unless overridden, as explained earlier). -. Place a `@ShellCommandGroup` on the package (through `package-info.java`) -in which the command is defined. This applies to all the commands defined in the -package (unless overridden at the method or class level, as explained earlier). The following listing shows an example: [source,java] ---- +@Command public class UserCommands { - @ShellMethod(value = "This command ends up in the 'User Commands' group") + @Command(description = "This command ends up in the 'Default' group") public void foo() {} - @ShellMethod(value = "This command ends up in the 'Other Commands' group", + @Command(description = "This command ends up in the 'Other Commands' group", group = "Other Commands") public void bar() {} } ... -@ShellCommandGroup("Other Commands") +@Command(group = "Other Commands") public class SomeCommands { - @ShellMethod(value = "This one is in 'Other Commands'") + @Command(description = "This one is in 'Other Commands'") public void wizz() {} - @ShellMethod(value = "And this one is 'Yet Another Group'", + @Command(description = "And this one is 'Yet Another Group'", group = "Yet Another Group") public void last() {} } diff --git a/spring-shell-docs/modules/ROOT/pages/commands/writing.adoc b/spring-shell-docs/modules/ROOT/pages/commands/writing.adoc index 61b58e5ee..bc3578382 100644 --- a/spring-shell-docs/modules/ROOT/pages/commands/writing.adoc +++ b/spring-shell-docs/modules/ROOT/pages/commands/writing.adoc @@ -29,5 +29,5 @@ It's possible to autowire `Terminal` to get access to its writer. [source, java, indent=0] ---- -include::{snippets}/WritingSnippets.java[tag=legacyanno-terminal-writer] +include::{snippets}/WritingSnippets.java[tag=inject-terminal-writer] ---- diff --git a/spring-shell-docs/modules/ROOT/pages/completion.adoc b/spring-shell-docs/modules/ROOT/pages/completion.adoc index 91b4fd879..82b2a8c47 100644 --- a/spring-shell-docs/modules/ROOT/pages/completion.adoc +++ b/spring-shell-docs/modules/ROOT/pages/completion.adoc @@ -37,7 +37,7 @@ include::{snippets}/CompletionSnippets.java[tag=builder-1] ---- Option values with annotation based command registration are handled -via `ValueProvider` interface which can be defined with `@ShellOption` +via `CompletionProvider` interface which can be defined with `@OptionValues` annotation. [source, java, indent=0] @@ -45,7 +45,7 @@ annotation. include::{snippets}/CompletionSnippets.java[tag=provider-1] ---- -Actual `ValueProvider` with annotation based command needs to be +Actual `CompletionProvider` with annotation based command needs to be registered as a _Bean_. [source, java, indent=0] diff --git a/spring-shell-docs/modules/ROOT/pages/execution.adoc b/spring-shell-docs/modules/ROOT/pages/execution.adoc index b238d4033..0630200f1 100644 --- a/spring-shell-docs/modules/ROOT/pages/execution.adoc +++ b/spring-shell-docs/modules/ROOT/pages/execution.adoc @@ -20,7 +20,7 @@ Some commands may not have any useful meanings when they run in interactive mode or (conversely) in non-interactive mode. For example, a built-in `exit` command would have no meaning in non-interactive mode, because it is used to exit interactive mode. -The `@ShellMethod` annotation has a field called `interactionMode` that you can use to inform +The `@Command` annotation has a field called `interactionMode` that you can use to inform shell about when a particular command is available. [[using-shell-execution-shellrunner]] diff --git a/spring-shell-docs/src/test/java/org/springframework/shell/docs/CommandRegistrationInteractionModeSnippets.java b/spring-shell-docs/src/test/java/org/springframework/shell/docs/CommandRegistrationInteractionModeSnippets.java index c97ebe87f..24457cdf9 100644 --- a/spring-shell-docs/src/test/java/org/springframework/shell/docs/CommandRegistrationInteractionModeSnippets.java +++ b/spring-shell-docs/src/test/java/org/springframework/shell/docs/CommandRegistrationInteractionModeSnippets.java @@ -16,8 +16,8 @@ package org.springframework.shell.docs; import org.springframework.shell.command.CommandRegistration; +import org.springframework.shell.command.annotation.Command; import org.springframework.shell.context.InteractionMode; -import org.springframework.shell.standard.ShellMethod; public class CommandRegistrationInteractionModeSnippets { @@ -38,7 +38,7 @@ CommandRegistration commandRegistration() { static class Dump1 { // tag::snippet2[] - @ShellMethod(key = "mycommand", interactionMode = InteractionMode.INTERACTIVE) + @Command(command = "mycommand", interactionMode = InteractionMode.INTERACTIVE) public void mycommand() { } // end::snippet2[] diff --git a/spring-shell-docs/src/test/java/org/springframework/shell/docs/CompletionSnippets.java b/spring-shell-docs/src/test/java/org/springframework/shell/docs/CompletionSnippets.java index 60b13fb5d..51d2df3d9 100644 --- a/spring-shell-docs/src/test/java/org/springframework/shell/docs/CompletionSnippets.java +++ b/spring-shell-docs/src/test/java/org/springframework/shell/docs/CompletionSnippets.java @@ -22,10 +22,11 @@ import org.springframework.shell.CompletionContext; import org.springframework.shell.CompletionProposal; import org.springframework.shell.command.CommandRegistration; +import org.springframework.shell.command.annotation.Command; +import org.springframework.shell.command.annotation.Option; +import org.springframework.shell.command.annotation.OptionValues; +import org.springframework.shell.completion.CompletionProvider; import org.springframework.shell.completion.CompletionResolver; -import org.springframework.shell.standard.ShellMethod; -import org.springframework.shell.standard.ShellOption; -import org.springframework.shell.standard.ValueProvider; public class CompletionSnippets { @@ -57,10 +58,10 @@ public List apply(CompletionContext t) { // end::resolver-1[] // tag::provider-1[] - static class MyValuesProvider implements ValueProvider { + static class MyCompletionProvider implements CompletionProvider { @Override - public List complete(CompletionContext completionContext) { + public List apply(CompletionContext completionContext) { return Arrays.asList("val1", "val2").stream() .map(CompletionProposal::new) .collect(Collectors.toList()); @@ -70,9 +71,9 @@ public List complete(CompletionContext completionContext) { static class Dump1 { // tag::anno-method[] - @ShellMethod(value = "complete", key = "complete") + @Command(command = "complete", description = "complete") public String complete( - @ShellOption(valueProvider = MyValuesProvider.class) String arg1) + @Option @OptionValues(provider = "myCompletionProvider") String arg1) { return "You said " + arg1; } diff --git a/spring-shell-docs/src/test/java/org/springframework/shell/docs/UiComponentSnippets.java b/spring-shell-docs/src/test/java/org/springframework/shell/docs/UiComponentSnippets.java index 40b0dc29c..97319eed1 100644 --- a/spring-shell-docs/src/test/java/org/springframework/shell/docs/UiComponentSnippets.java +++ b/spring-shell-docs/src/test/java/org/springframework/shell/docs/UiComponentSnippets.java @@ -25,6 +25,7 @@ import org.jline.utils.AttributedString; import org.jline.utils.AttributedStringBuilder; +import org.springframework.shell.command.annotation.Command; import org.springframework.shell.component.ConfirmationInput; import org.springframework.shell.component.MultiItemSelector; import org.springframework.shell.component.PathInput; @@ -40,8 +41,6 @@ import org.springframework.shell.component.StringInput.StringInputContext; import org.springframework.shell.component.support.SelectorItem; import org.springframework.shell.standard.AbstractShellComponent; -import org.springframework.shell.standard.ShellComponent; -import org.springframework.shell.standard.ShellMethod; import org.springframework.util.StringUtils; public class UiComponentSnippets { @@ -72,7 +71,7 @@ public List apply(StringInputContext context) { class Dump1 extends AbstractShellComponent { // tag::snippet2[] - @ShellMethod(key = "component stringcustom", value = "String input", group = "Components") + @Command(command = "component stringcustom", description = "String input", group = "Components") public String stringInputCustom(boolean mask) { StringInput component = new StringInput(getTerminal(), "Enter value", "myvalue", new StringInputCustomRenderer()); @@ -89,10 +88,10 @@ public String stringInputCustom(boolean mask) { class Dump2 { // tag::snippet3[] - @ShellComponent + @Command public class ComponentCommands extends AbstractShellComponent { - @ShellMethod(key = "component string", value = "String input", group = "Components") + @Command(command = "component string", description = "String input", group = "Components") public String stringInput(boolean mask) { StringInput component = new StringInput(getTerminal(), "Enter value", "myvalue"); component.setResourceLoader(getResourceLoader()); @@ -109,10 +108,10 @@ public String stringInput(boolean mask) { class Dump3 { // tag::snippet4[] - @ShellComponent + @Command public class ComponentCommands extends AbstractShellComponent { - @ShellMethod(key = "component path input", value = "Path input", group = "Components") + @Command(command = "component path input", description = "Path input", group = "Components") public String pathInput() { PathInput component = new PathInput(getTerminal(), "Enter value"); component.setResourceLoader(getResourceLoader()); @@ -126,10 +125,10 @@ public String pathInput() { class Dump4 { // tag::snippet5[] - @ShellComponent + @Command public class ComponentCommands extends AbstractShellComponent { - @ShellMethod(key = "component confirmation", value = "Confirmation input", group = "Components") + @Command(command = "component confirmation", description = "Confirmation input", group = "Components") public String confirmationInput(boolean no) { ConfirmationInput component = new ConfirmationInput(getTerminal(), "Enter value", !no); component.setResourceLoader(getResourceLoader()); @@ -143,10 +142,10 @@ public String confirmationInput(boolean no) { class Dump5 { // tag::snippet6[] - @ShellComponent + @Command public class ComponentCommands extends AbstractShellComponent { - @ShellMethod(key = "component single", value = "Single selector", group = "Components") + @Command(command = "component single", description = "Single selector", group = "Components") public String singleSelector() { SelectorItem i1 = SelectorItem.of("key1", "value1"); SelectorItem i2 = SelectorItem.of("key2", "value2"); @@ -166,10 +165,10 @@ public String singleSelector() { class Dump6 { // tag::snippet7[] - @ShellComponent + @Command public class ComponentCommands extends AbstractShellComponent { - @ShellMethod(key = "component multi", value = "Multi selector", group = "Components") + @Command(command = "component multi", description = "Multi selector", group = "Components") public String multiSelector() { List> items = new ArrayList<>(); items.add(SelectorItem.of("key1", "value1")); @@ -191,10 +190,10 @@ public String multiSelector() { } class Dump7 { - @ShellComponent + @Command public class ComponentCommands extends AbstractShellComponent { - @ShellMethod(key = "component single", value = "Single selector", group = "Components") + @Command(command = "component single", description = "Single selector", group = "Components") public String singleSelector() { // tag::snippet8[] SelectorItem i1 = SelectorItem.of("key1", "value1"); @@ -215,10 +214,10 @@ public String singleSelector() { } class Dump8 { - @ShellComponent + @Command public class ComponentCommands extends AbstractShellComponent { - @ShellMethod(key = "component path input", value = "Path search", group = "Components") + @Command(command = "component path input", description = "Path search", group = "Components") public String pathSearch() { // tag::snippet9[] PathSearchConfig config = new PathSearch.PathSearchConfig(); diff --git a/spring-shell-docs/src/test/java/org/springframework/shell/docs/WritingSnippets.java b/spring-shell-docs/src/test/java/org/springframework/shell/docs/WritingSnippets.java index dc2709d4e..4b97f02cb 100644 --- a/spring-shell-docs/src/test/java/org/springframework/shell/docs/WritingSnippets.java +++ b/spring-shell-docs/src/test/java/org/springframework/shell/docs/WritingSnippets.java @@ -27,16 +27,16 @@ class WritingSnippets { class Dump1 { - // tag::legacyanno-terminal-writer[] + // tag::inject-terminal-writer[] @Autowired Terminal terminal; - @ShellMethod + @Command public void example() { terminal.writer().println("hi"); terminal.writer().flush(); } - // end::legacyanno-terminal-writer[] + // end::inject-terminal-writer[] } class Dump2 {