Versions Compared
Key
- This line was added.
- This line was removed.
- Formatting was changed.
In Part 1 we created an add-on, which contains three SIL
...
functions.
In Part 2 we will discuss, what should be changed in this add-on to add your own
...
function.
1. Create your own class for your
...
function
First of all you need to create your own class in the
...
function folder. This class must extend
...
the AbstractSILFunction<T> class.
Let's look at the available files in this folder (these files are provided as an example. If you develop you own add-on, you can remove these files).
SayHello.java:
Code Block |
---|
public class SayHello extends |
...
AbstractSILFunction<MutableString> { private static final SILType[][] types = {{ TypeInst.STRING }}; public SayHello(ClassLoader classLoader, String name) { super(classLoader, name, types); } Override public SILType<MutableString> getReturnType() { return TypeInst.STRING; } @Override protected SILValue<MutableString> |
...
runFunction(SILContext silContext, List<SILValue<?>> list) { SILValue param = list.get(0); return SILValueFactory.string( "Hello " + param.toStringValue()); } @Override public String getParams() { return "(name)"; } |
Let's have a look at the first line:
...
Code Block |
---|
private static final SILType[][] types = {{ TypeInst.STRING }}; |
This line defines, what kind of input variables to expect for this
...
function. We call methods in SIL like this:
Code Block |
---|
mymethod(myparameter); |
...
By types = {{ TypeInst.STRING }}; we say that myparameter is a string. If you want to pass two parameters to mymethod then the line will be like this:
Code Block |
---|
private static final SILType[][] types = {{ TypeInst.STRING, TypeInst.STRING }}; |
and you can call your method like this:
Code Block |
---|
mymethod(myparameter1, myparameter2); |
If your
...
function can take either one parameter or two parameters, then you should define it like this:
Code Block |
---|
private static final SILType[][] types = {{ TypeInst.STRING},
{TypeInst.STRING, TypeInst.STRING }}; |
Next line:
Code Block |
---|
public class SayHello extends |
...
AbstractSILFunction<MutableString> |
As you can see this class is extended from
...
AbstractSILFunction<MutableString>, which means that this
...
function will return the String type.
Next lines:
Code Block |
---|
public SayHello(ClassLoader classLoader, String name) {
super(classLoader, name, types);
} |
These lines define a constructor. You do not need to change anything there.
Next lines:
Code Block |
---|
Override
public SILType<MutableString> getReturnType() { return TypeInst.STRING; } |
These lines define a function, which informs the SIL engine what object will be returned by this
...
function. We will return a String.
Next lines:
Code Block |
---|
@Override
protected SILValue<MutableString> |
...
runFunction(SILContext silContext, List<SILValue<?>> list) { SILValue param = list.get(0); return SILValueFactory.string( "Hello " + param.toStringValue()); } |
These lines provide the logic, which will be executed by your
...
function. This is the entry point for your
...
function. This function accepts two parameters.
silContext (you can find here system variables like the issue, for which the script is executed, sil variables).
For example, if you need to take the issue for which the script is executed, you can use a code like this:
Code Block |
---|
Issue issue = (Issue) silContext.getAllMetaInformation().get("issue"); |
The list parameter, is the parameter for your input variables.
Line
Code Block |
---|
SILValueFactory.string( "Hello " + param.toStringValue()) |
returns a value from the
...
function. You should use the SILValueFactory class to create return values for your
...
function. This class can create all kind of value types available in SIL. We will see more examples later.
So, this
...
function actually just accept a parameter and return a result Hello + this parameter. You can implement any logic you need in this function.
Next lines:
Code Block |
---|
@Override
public String getParams() { return "(name)"; } |
These lines define how your function will look in the SIL Manager. When you start typing in the SIL manager, you see suggestions for available
...
functions. the (name) string means that the suggestion will look like this:
Code Block |
---|
yourmethod(name) |
2. Add your class to SIL engine
We created a class, but how to tell the SIL engine how to use it? It is done in the ESLauncher.java file. You can see there lines like this one:
Code Block |
---|
...
FunctionRegistry.register(new SayHello( classLoader,"SayHello")); |
It says that we add the
...
function from the SayHello class and it will be called SayHello.
What you need is to copy the line and change first SayHello to your class and the next SayHello to your name. The name of the class and the name of the
...
function in SIL can be different.
Then also add a line like this:
Code Block |
---|
...
FunctionRegistry.unregister("SayHello"); |
Change SayHello to the name of your
...
function. It will unload your
...
function, if you disable your add-on.
3. More on SIL
You can see in SayHello2, we return a List as a return value.
Code Block |
---|
SILValue param1 = list.get(0);
SILValue param2 = list.get(1);
List<String> res = new ArrayList<>();
res.add("Hello " + param1.toStringValue());
res.add("Hello " + param2.toStringValue());
return SILValueFactory.stringArray(res); |
where res is a List<String>.
To make it work you also need to change the return type to TypeInst.STRING_ARR and
...
extend AbstractSILFunction with KeyableArraySILObject<MutableString> type.
In SIL you can use this
...
function like this:
Code Block |
---|
string[] res = SayHello2("Alexey", "Matveev");
runnerLog(res[0]);
runnerLog(res[1]); |
In SayHello3 we return a Map:
Code Block |
---|
SILValue param1 = list.get(0);
SILValue param2 = list.get(1);
Map<String, String> res = new HashMap<>();
res.put("param1","Hello " + param1.toStringValue());
res.put("param2","Hello " + param2.toStringValue());
return SILValueFactory.stringArray(res); |
You can use SayHello3 in SIL like this:
Code Block |
---|
res = SayHello3("Alexey", "Matveev");
runnerLog(res["param1"]);
runnerLog(res["param2"]); |
We call the SIL array not by index, but by key. But if you notice, these functions have the same code to return a value:
Code Block |
---|
return SILValueFactory.stringArray(res); |
It is because in SIL the KeyableArraySILObject contains a List and a Map to provide keys for the List, that is why the code is the same.
4. Pass an array as a parameter
Now we know how to pass a string parameter to a SIL
...
function and return a string, a List or a Map.
Now let's have a look on how to pass an array as a parameter.
The
...
runFunction function will look like this:
Code Block |
---|
@Override
protected SILValue<MutableString> |
...
runFunction(SILContext silContext, List<SILValue<?>> list) { GenericArraySILObject rowsToUpdate = (GenericArraySILObject) list.get(0).getObject(); Map<String, int[]> keys = rowsToUpdate.getKeysMapping() ...... } |
First you convert the parameter to the GenericArraySILObject class and then convert it to Java's Map.
You could use this
...
function in SIL like this:
Code Block |
---|
string[] arr;
arr["key1"] = "value1";
arr["key2"] = "value2";
yourmethod(arr); |
That is all I wanted to talk about in this article. I hope that now you have a good intro in developing your own add-on for the SIL engine.
Contents
Table of Contents |
---|