Step 2: Creating A New SIL Function
On this page:
MyReverseString()
For this example, let's suppose that we need to reverse certain strings within Jira, and a reverse string function might be handy. Since SIL™ does not provide such a function, let's implement it.
In the main package (com.mycompany.silexample) create a new class and name it ReverseStringFunction.
The code is presented below, along with the comments.
/*
* Created at Sep 2, 2011T5:39:27 PM+02.
*
* File: ReverseStringFunction.java
*/
package com.mycompany.silexample;
import java.util.*;
import com.keplerrominfo.common.util.MutableString;
import com.keplerrominfo.sil.lang.*;
import com.keplerrominfo.sil.lang.type.TypeInst;
import com.keplerrominfo.sil.lang.SILValue;
import com.keplerrominfo.sil.lang.SILValueFactory;
/**
* Reverses a string
*
* @author Radu Dumitriu (rdumitriu@gmail.com)
* @since 1.0
*/
public class ReverseStringFunction extends AbstractFunction<MutableString> {
private static final SILType[][] types = {{ TypeInst.STRING }}; //all possible type combinations are listed here
public ReverseStringFunction(String name) {
super(name, types);
}
/**
* Returns the type of the returned value. For functions that return
* a value of variable type, this should return null
*
* @return the type of the returned value
*/
@Override
public SILType<MutableString> getReturnType() {
return TypeInst.STRING;
}
/**
* The execution of the function
* @param silValues the list of values (parameters)
* @return the SIL value
*/
@Override
protected SILValue<MutableString> executeFunction(SILContext context, List<SILValue<?>> silValues) {
//AbstractFunction checks the parameters and their types
SILValue param = silValues.get(0);
//We know for sure this is a string
String val = param.toStringValue();
//we calculate the reversed value
String reversedVal = new StringBuilder(val).reverse().toString();
//We'll prepare the return here
return SILValueFactory.string(reversedVal);
}
/**
* This returns the description of the parameters
* @return the part that will be appended to the function at editing time
*/
@Override
public String getParams() {
return "(str)"; //that's all
}
}
The function is now completed, now you need to register it on the SIL™. To do this, modify the launcher you created in the previous step.
@Override
public void doAtLaunch() {
super.doAtLaunch();
//register the function
FunctionRegistry.register(new ReverseStringFunction("myReverseString"));
}
@Override
public void doAtStop() {
//first, make sure that super is called, even if will have an exception here
try {
//unregister the function
FunctionRegistry.unregister("myReverseString");
} catch(Exception e) {
LOG.error("Failed to unregister!", e);
}
super.doAtStop();
}
Things happening under the hood
The above function inherits a lot of the functionality from AbstractFunction, and this class is responsible for:
Checking the type of the parameters
Converting the parameters to the required types automatically
Calling the real execution code with the parameters transformed.
The AbstractFunction class follows a Template Method Pattern. You are not required to inherit AbstractFunction. In fact, sometimes you should implement a function interface to avoid or implement custom checking of the parameters.
Don't forget to unit test your code. We didn't include it in the example, but you should feel obliged to do it.
Running the example
Open a terminal or a console and run atlas-debug in the root of the project. It will launch Jira with both SIL Engine™ and silexample add-ons installed.
In the SIL Manager, open a test .sil file and write something like:
string myString = myReverseString("Appfire");
If everything is fine, the editor will auto-complete the function.