Step by Step Simple Java Command
1. What You Will Learn
In this tutorial you will learn how to write a simple Command step by step in Java.
Each essential element is thoroughly explained and at the end you can write your own simple Commands based on the insights gained.
This guide shall show how to write a Command and will not touch the topics how to use them in the Editor or Executor applications. For these you can follow the guide Build and Run your first Command. |
2. Prerequisites
To complete this guide you need:
-
Roughly 10 minutes
-
JDK11+ installed with JAVA_HOME configured appropriately
-
An IDE (we recommend IntelliJ)
-
Some kind of build tool (like gradle, maven or ant)
3. What is a Command?
A Command is some small executable code, which can be fed with inputs, executes its code and may produce an output.
The in- and outputs then can be served to other Commands which results in a chaining of Commands.
It is important for a Command to not do many tasks at once, but focus on one task and let other Commands do the rest.
4. Step by Step
In the following parts we want to develop a simple Command step by step. Beginning from the bare minimum and ending with a fully functional and documented Command.
4.1. The Example We Want to Develop
We want to show how to develop a Command along an example to better follow along. In this guide we want to develop a simple Adding Command which takes two numbers adds them up and returns the result.
This will be the base on which the essentials are explained and will be used in advanced lessons later on.
4.2. Dependencies We Need
To write a functional Command which can be used by the Java Command Interpreter of PAK, we need to have some dependencies included:
Dependencies | Reason to include |
---|---|
de.asap.pak.jlcint:jlcint-processor |
We use this dependency for the annotation processing. Include this to your annotation processor during compilation so that command-metas are generated. |
de.asap.pak.jlcint:jlcint-commandapi |
Provides annotations used to develop a Java Command |
4.3. Bare Bones of a Command
The following code shows the skeleton of a Java Command. We will go over each element and explain its functionality.
This will be the foundation on top we will develop a Command.
@JavaCommand (2)
public class Adding { (1)
@Run (3)
public void run(){
}
}
1 | Every Java Command is a Java Class. By default, the name of the class is also the name of the Command. In our example we created a Command named ‚Adding‘. |
2 | The @JavaCommand -Annotation marks the created class as a Command. Every Class that is a Command needs that annotation. |
3 | Every Command executes code. To define what code the Command executes, a public void method needs to be annotated with @Run . This method will be the entry point of the Command when it is run.The name of the method itself can be chosen freely, as long it is not named like a possible setter/getter of a class field. |
When the class name is in CamelCase then the Command name will be the class name split at the capital letters. Consecutive capital letters are not split. Example: HelloWorld → Hello World , TheABC → The ABC
|
4.4. Command In- and Outputs
The Adding Command needs two numbers as inputs and a number as an output. The in- and outputs are defined through the class fields annotated with @Persistent
.
@JavaCommand
public class Adding {
@Persistent (1)
private int numberOne;
@Persistent (1)
private int numberTwo;
@Persistent(scope = FieldScope.WRITE_ONLY) (2)
private int result;
@Run
public void run(){
}
}
1 | A class field annotated with a simple @Persistent represents a mandatory input of the Command. We want to have two numbers (numberOne and numberTwo ) as inputs, so we annotate both fields like in the example. |
2 | The Command needs one output, the result of the addition. For this the field result is also annotated with @Persistent but the annotation has more information added to it.As annotated fields are recognized as inputs by default, we need to tell the annotation that the underlying field should be handled as an output. This can be done by defining the scope FieldScope.WRITE_ONLY . |
4.5. Running Code
To have a fully functional Command only one last thing is missing. The code to run when the Command is executed. As already explained in Bare Bones of a Command the method annotated with @Run
is the code entry point for execution. So we add the desired Command functionality to this method.
@JavaCommand
public class Adding {
@Persistent
private int numberOne;
@Persistent
private int numberTwo;
@Persistent(scope = FieldScope.WRITE_ONLY)
private int result;
@Run
public void run(){
this.result = this.numberOne + this.numberTwo; (1) (2)
}
}
1 | Due to the inputs being mandatory, they are already set in the fields at runtime of the Command. We do not need to worry about unset fields and NullpointerExceptions and can safely add the two numbers. |
2 | The output is set when the field is set with a value. In this case, the output field result is set to the sum of our two numbers. |
In case in- or outputs are not set (null) when a Command is running, then an exception telling you that, will be thrown and the Command fails. |
4.6. Documentation of a Command
The last step for a Command is to document what the Command does, what the inputs require and what the outputs produce. This is achieved by documenting the elements and using the JavaDoc-Tag
@workflowDocu
.
All documentation written this way will be exposed to the users of the Command and helps guide the usage.
/**
* @workflowDocu This Command adds two numbers together and returns the result. (1)
*/
@JavaCommand
public class Adding {
/**
* @workflowDocu The first number to be added to second number. (2)
*/
@Persistent
private int numberOne;
/**
* @workflowDocu The second number to be added to the first number. (2)
*/
@Persistent
private int numberTwo;
/**
* @workflowDocu The result of the two numbers added together. (2)
*/
@Persistent(scope = FieldScope.WRITE_ONLY)
private int result;
/**
* Method that adds two numbers together (3)
*/
@Run
public void run(){
this.result = this.numberOne + this.numberTwo;
}
}
1 | The overall documentation of the Command, should give an overview over its functionality. |
2 | The documentation of the in- and outputs should provide the user an explanation what the Command expects it to be. Any constraints on the values are also added here so they can be upheld. |
3 | The @Run -Method doesn’t get a @workflowDocu Tag and its documentation won’t be presented to the user. But you can also document the method when you like. |
5. Summary
We learned how to write a simple Java Command, that can add two numbers. This can be used as a basis for more advanced Commands and is a great start to begin the development of your own.
6. What to Do Next?
After creating your own simple Command the only thing left to do is to compile your Command with the jlcint-annotation-processor.
-
To see how to perform a unit test on a Command follow the UnitTest Simple Java Command guide.
-
The guide Build and Run your first Command could be interesting for you, when you want to build and use this Command in the executor.
-
If you want to know how to extend your command using services, refer to this guice.