Skip to content

Commit 6ef8aa3

Browse files
committed
docs: add documentation on command creation and command manager configuration
1 parent 388f67e commit 6ef8aa3

21 files changed

+410
-4
lines changed

docs/annotated/annotated.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,20 @@ using annotated classes and methods.
66
The annotated command API is just an alternative way to create `Command` instances,
77
we use this instead of the classic `Command.builder(String)` method.
88

9+
### Comparison
10+
11+
You can make a side-by-side comparison of the two approaches in the following table
12+
and links:
13+
14+
| Imperative | Annotated |
15+
|----------------------------------------------------------------------------|-------------------------------------------------------------------------|
16+
| [Basic Command Creation](../imperatively/basic.md) | [Basic Command Creation](../annotated/basic.md) |
17+
| [Command with single Argument](../imperatively/argument.md) | [Command with single Argument](../annotated/argument.md) |
18+
| [Command with multiple Arguments](../imperatively/multiple-arguments.md) | [Command with multiple Arguments](../annotated/multiple-arguments.md) |
19+
| [Command with optional Arguments](../imperatively/optional-arguments.md) | [Command with optional Arguments](../annotated/optional-arguments.md) |
20+
921
### Elements of the Annotated Command API
1022

11-
The annotated command API is composed of 3 elements:
23+
The annotated command API is composed of:
1224
- The `@Command` annotation and others.
1325
- The `AnnotatedCommandTreeBuilder` interface

docs/annotated/argument.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## #2 With Arguments
2+
3+
Check this command example with a single argument:
4+
5+
```java
6+
@Command(names = "hello")
7+
public class TestCommand implements CommandClass {
8+
9+
@Command(names = "")
10+
public void run(String name) {
11+
System.out.println("Hi " + name);
12+
}
13+
14+
}
15+
```
16+
17+
In this example:
18+
- Executing `hello yusshu` will print `Hi yusshu`
19+
- Executing `hello Fixed` will print `Hi Fixed`
20+
- Executing `hello` will result in an error

docs/annotated/basic.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## #1 Basic Command
2+
3+
Check this basic command example, with no arguments, no subcommands and no permissions,
4+
using the annotated command creation approach:
5+
6+
```java
7+
@Command(names = "test")
8+
public class TestCommand implements CommandClass {
9+
10+
@Command(names = "")
11+
public void run() {
12+
System.out.println("Hello World!");
13+
}
14+
15+
}
16+
```
17+
18+
Executing `test` will print `Hello World!`

docs/annotated/index.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@ annotated.md
22
command-class.md
33
command-tree-builder.md
44
part-injector.md
5-
subcommand-instance-creator.md
5+
subcommand-instance-creator.md
6+
basic.md
7+
argument.md
8+
multiple-arguments.md
9+
optional-arguments.md

docs/annotated/multiple-arguments.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## #3 Command with Multiple Args
2+
3+
This example shows how to create a command with multiple arguments
4+
using the annotated approach:
5+
6+
```java
7+
@Command(names = "greet")
8+
public class GreetingCommand implements CommandClass {
9+
10+
@Command(names = "")
11+
public void run(String name, boolean formal) {
12+
if (formal) {
13+
System.out.println("Hello, " + name + "!");
14+
} else {
15+
System.out.println("Hi, " + name + "!");
16+
}
17+
}
18+
19+
}
20+
```
21+
22+
- Executing `greet John false` will print `Hi, John!`
23+
- Executing `greet John true` will print `Hello, John!`
24+
- Executing `greet John` will result in a usage error
25+
- Executing `greet` will result in a usage error

docs/annotated/optional-arguments.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
## #4 With Optional Args
2+
3+
This example shows how to create a command with optional arguments
4+
with the annotated approach:
5+
6+
```java
7+
@Command(names = "greet")
8+
public class GreetingCommand implements CommandClass {
9+
10+
@Command(names = "")
11+
public void run(String name, @OptArg("Mr.") String title) {
12+
System.out.println("Hello, " + title + " " + name + "!");
13+
}
14+
15+
}
16+
```
17+
18+
The `@OptArg` annotation is used to mark an argument as optional, and
19+
it accepts a default value as a parameter, which will be used if the
20+
argument is not present in the input.
21+
22+
- Executing `greet John` will print `Hello, Mr. John!`
23+
- Executing `greet John Dr.` will print `Hello, Dr. John!`
24+
- Executing `greet John Mr.` will print `Hello, Mr. John!`

docs/concepts/index.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
command.md
22
command-manager.md
33
command-part.md
4-
command-context.md
4+
command-context.md
5+
namespaces.md

docs/concepts/namespaces.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
## Namespaces
2+
3+
*(If you use an already implemented platform and annotated commands, you don't need
4+
to use Namespaces, yay!)*
5+
6+
A namespace is a mapping/set of the arguments that are injected into the execution.
7+
For example, we can inject the user executor of a command and use it later.
8+
9+
Creating a namespace:
10+
<!--@formatter:off-->
11+
```java
12+
// Create a namespace
13+
Namespace namespace = Namespace.create();
14+
```
15+
<!--@formatter:on-->
16+
17+
Now we can set any object in the namespace, by type and name, for example, suppose we
18+
have a `User` class:
19+
<!--@formatter:off-->
20+
```java
21+
namespace.setObject(User.class, "USER", new User("Fixed", 16));
22+
```
23+
<!--@formatter:on-->
24+
25+
And now, we can retrieve the object from the namespace, using the exact same
26+
type and name, for example:
27+
<!--@formatter:off-->
28+
```java
29+
User user = namespace.getObject(User.class, "USER");
30+
31+
System.out.println(user.getName()); // Fixed
32+
```
33+
<!--@formatter:on-->
34+

docs/configuration/authorizer.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
## Authorizer
2+
3+
`command-flow` has a functional interface `Authorizer` with a single method responsible for
4+
determining if a command should be executed.
5+
6+
### Platform Specific
7+
8+
There are some platform specific implementations of `Authorizer`, which are automatically
9+
set if you use the specific `CommandManager` class, for example, if you instantiate the
10+
`BukkitCommandManager`, it will already use the `BukkitAuthorizer` by default, awesome!
11+
12+
### Implementation
13+
14+
The `Authorizer` single method accepts a `Namespace` and the actual permission string,
15+
and returns a boolean value indicating if the command should be executed or not.
16+
17+
Check the following implementation example, suppose we have a `User` class, and we have
18+
previously set the sender user instance in the execution namespace *(Check page about
19+
Command Dispatch)*
20+
21+
<!--@formatter:off-->
22+
```java
23+
public class MyAuthorizer implements Authorizer {
24+
@Override
25+
public boolean isAuthorized(Namespace namespace, String permission) {
26+
User user = namespace.getObject(User.class, "USER");
27+
28+
// User not set!
29+
if (user == null) {
30+
return false;
31+
}
32+
33+
return user.hasPermission(permission);
34+
}
35+
}
36+
```
37+
<!--@formatter:on-->
38+
39+
Now we can set our `Authorizer` in the `CommandManager`
40+
41+
<!--@formatter:off-->
42+
```java
43+
CommandManager commandManager = ...;
44+
45+
commandManager.setAuthorizer(new MyAuthorizer());
46+
```
47+
<!--@formatter:on-->
48+
49+
### Permission String
50+
51+
The permission string is an optional attribute for `Command` instances, set during
52+
its instantiation, for example:
53+
54+
Using builders:
55+
<!--@formatter:off-->
56+
```java
57+
Command command = Command.builder("test")
58+
.permission("this.is.the.permission.string")
59+
.action(context -> {
60+
System.out.println("Hello World!");
61+
})
62+
.build();
63+
```
64+
<!--@formatter:on-->
65+
66+
Or annotations:
67+
<!--@formatter:off-->
68+
```java
69+
@Command(names = "test", permission = "this.is.the.permission.string")
70+
public class TestCommand implements CommandClass {
71+
...
72+
}
73+
```
74+
<!--@formatter:on-->

docs/configuration/configuration.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## Configuring the Command Manager
2+
3+
The `CommandManager` allows developers to fully configurate its behavior and
4+
how to determine certain aspects of the command parsing & dispatching process.
5+
6+
The `CommandManager` can also be extended for platform-specific features and
7+
native integration, like, automatically registering commands in a platform
8+
command registry.

docs/configuration/index.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
configuration.md
2+
authorizer.md
3+
tokenizer.md

docs/configuration/tokenizer.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Input Tokenizer
2+
3+
The input tokenizer is responsible for converting a simple input string into a
4+
list of tokens. The tokens are then used by the parser to enter the desired
5+
command path and either dispatch a command or get suggestions for the next
6+
token.
7+
8+
The `InputTokenizer` is a functional interface that can be set to the
9+
`CommandManager` via the `CommandManager#setInputTokenizer` method.
10+
11+
For example:
12+
13+
```java
14+
// create a tokenizer
15+
InputTokenizer tokenizer = ...;
16+
17+
// set the tokenizer
18+
CommandManager manager = ...;
19+
manager.setInputTokenizer(tokenizer);
20+
```
21+
22+
### Default Implementations
23+
24+
`command-flow` provides two default implementations of the `InputTokenizer`
25+
interface, `StringSpaceTokenizer` and `QuotedSpaceTokenizer`:
26+
27+
- `StringSpaceTokenizer` - This tokenizer splits the input string by spaces
28+
and returns the resulting tokens. This is the default tokenizer used by
29+
`CommandManager` if no other tokenizer is set.
30+
- `QuotedSpaceTokenizer` - This tokenizer splits the input string by spaces
31+
but also supports quoted strings. For example, the input string
32+
`hello "world of commands"` would be split into the tokens `hello` and
33+
`world of commands`.
34+
35+

docs/dispatch/index.txt

Whitespace-only changes.

docs/imperatively/argument.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## #2 With Arguments
2+
3+
Check this command example with a single argument:
4+
5+
<!--@formatter:off-->
6+
```java
7+
import static me.fixeddev.commandflow.part.Parts.*;
8+
9+
//...
10+
11+
// create an (argument) part of type string, with the name 'name'
12+
CommandPart nameArg = string("name");
13+
14+
// create the command
15+
Command helloCommand = Command.builder("hello")
16+
.addPart(nameArg)
17+
.action(context -> {
18+
// get the value of the name argument and print 'Hi <name>'
19+
context.<String>getValue(nameArg).ifPresent(name -> {
20+
System.out.println("Hi " + name);
21+
});
22+
})
23+
.build();
24+
```
25+
<!--@formatter:on-->
26+
27+
In this example:
28+
- Executing `hello yusshu` will print `Hi yusshu`
29+
- Executing `hello Fixed` will print `Hi Fixed`
30+
- Executing `hello` will print nothing

docs/imperatively/basic.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## #1 Basic Command
2+
3+
Check this basic command example, with no arguments, no subcommands and no permissions,
4+
using the imperative command creation approach:
5+
6+
<!--@formatter:off-->
7+
```java
8+
Command testCommand = Command.builder("test")
9+
.action(context -> {
10+
System.out.println("Hello World!");
11+
})
12+
.build();
13+
```
14+
<!--@formatter:on-->
15+
16+
Executing `test` will print `Hello World!`

docs/imperatively/index.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
intro.md
2+
basic.md
3+
argument.md
4+
multiple-arguments.md
5+
optional-arguments.md

docs/imperatively/intro.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## Imperative Command Creation
2+
3+
We can imperatively create commands using the command builder interface. This
4+
way to create commands is the most flexible one, but also the most verbose.
5+
6+
An alternative to this approach is to use the [annotation-based command creation](../annotated/annotated.md).
7+
8+
### Comparison
9+
10+
You can make a side-by-side comparison of the two approaches in the following table
11+
and links:
12+
13+
| Imperative | Annotated |
14+
|----------------------------------------------------------------------------|-------------------------------------------------------------------------|
15+
| [Basic Command Creation](../imperatively/basic.md) | [Basic Command Creation](../annotated/basic.md) |
16+
| [Command with single Argument](../imperatively/argument.md) | [Command with single Argument](../annotated/argument.md) |
17+
| [Command with multiple Arguments](../imperatively/multiple-arguments.md) | [Command with multiple Arguments](../annotated/multiple-arguments.md) |
18+
| [Command with optional Arguments](../imperatively/optional-arguments.md) | [Command with optional Arguments](../annotated/optional-arguments.md) |

0 commit comments

Comments
 (0)