在SIL中创建函数

大家好!

在本文中,我想告诉您如何在SIL中创建函数。

介绍


SIL代表“简单发布语言”,它是cPrime开发人员创建的,用于自动完成Atlassian Jira和Confluence中的手动操作。

SIL的主要优点是SIL包含不需要了解Atlassian Jira或Atlassian Confluence API即可使用的功能。这大大降低了进入SIL的门槛,并使SIL程序代码的体积比类似的Java或Groovy代码小。

例如,您想根据要求从吉拉(Jira)选择票证,以便可以对它们执行一些操作。为此,在Java或Groovy中,您将不得不编写许多代码。在SIL上,这是一行:

selectIssues(" JQL ");

此外,在Java或Groovy中,您必须确保Jira 7和Jira 8上的代码具有兼容性。在SIL中,您无需考虑兼容性。SelectIssues将在SIL支持的所有Jira版本上运行。

您可以在此处找到有关SIL的更多信息
但是,如果我需要执行类似的操作,为什么SIL中没有功能?例如,我需要从Table Grid Next Generation插件获取数据,或者使用Jira插件的PDF导出器生成PDF文件。

在这种情况下,您有两个选择:

  1. SIL Groovy Connector-此插件允许您使用Java或Groovy中的Jira Java API编写代码,并从SIL脚本调用此代码。
  2. 编写可将您的功能添加到SIL的Jira插件,然后在SIL脚本中使用您的功能

在本文中,我们将重点介绍如何编写Jira插件以扩展SIL的功能。为了重复本文中的步骤,您将需要Atlassian SDK和git。

设置Maven原型


扩展SIL的插件必须包含将功能添加到SIL的逻辑。为了不每次都将此逻辑添加到插件中,而是仅专注于编写函数,我做了一个Maven原型,它将创建新插件中所需的一切。

首先,从存储库克隆原型:

git clone https://alex1mmm@bitbucket.org/alex1mmm/sil-extension-archetype.git --branch v1 --single-branch

将创建sil-extensiontion-archetype文件夹。让我们开始吧:

cd sil-extension-archetype

现在,将原型安装在本地Maven存储库中:

atlas-mvn install

创建一个插件


转到上方的文件夹并创建一个新的插件

cd ..
atlas-mvn archetype:generate -DarchetypeCatalog=local

通过maven创建项目时,系统会询问您标准问题。我回答这些问题。您可以更改它们。

Choose archetype:

1: local -> com.cprime.jira.sil.extension:sil-extension-archetype (This is the com.cprime.jira.sil.extension:sil-extension plugin for Atlassian JIRA.)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 

Define value for property 'groupId': ru.matveev.alexey.sil.extension
Define value for property 'artifactId': sil-extension
Define value for property 'version' 1.0-SNAPSHOT: : 
Define value for property 'package' ru.matveev.alexey.sil.extension: : 

Confirm properties configuration:
groupId: ru.matveev.alexey.sil.extension
artifactId: sil-extension
version: 1.0-SNAPSHOT
package: ru.matveev.alexey.sil.extension

 Y: : Y

之后,将创建插件。

测试插件


转到创建的文件夹(在我的情况下是sil-extension)并运行Jira:

cd sil-extension
atlas-run</code>
 Jira   
<code>http://localhost:2990/jira/plugins/servlet/silmanager?autoSelectTree=sil.scripts

您将看到“ SIL管理器”屏幕。选择“新建文件”选项:



创建具有以下内容的test.sil文件:

runnerLog(SayHello("Alexey"));
string[] res = SayHello2("Alexey", "Matveev");
runnerLog(res[0]);
runnerLog(res[1]);
res = SayHello3("Alexey", "Matveev");
runnerLog(res["param1"]);
runnerLog(res["param2"]);

Jira中的屏幕将如下所示:



我们的插件添加了三个功能:SayHello,SayHello2,SayHello3。Test.sil检查是否已将功能添加到SIL。

通过单击“运行”按钮运行test.sil。在控制台选项卡中,您应该看到以下文本:

Hello Alexey
Hello Alexey
Hello Matveev
Hello Alexey
Hello Matveev
Done.

如果您看到这样的文字,则说明我们的功能已成功添加到SIL中。

现在,让我们讨论为了创建我们自己的功能需要在插件中进行哪些更改。

为我们的功能创建一个Java类


您要添加到SIL的每个函数必须具有自己的类。该类必须是AbstractSILRoutine类的后代。

为了了解需要添加到新类中的内容,让我们看一下可用的示例。

SayHello.java


public class SayHello extends AbstractSILRoutine<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> runRoutine(SILContext silContext,                                   List<SILValue<?>> list) { 
    SILValue param = list.get(0); 
    return SILValueFactory.string( "Hello " + param.toStringValue());
 }
  @Override 
  public String getParams() { return "(name)"; }

第一行:

private static final SILType[][] types = {{ TypeInst.STRING }};

该行定义了将传递给函数的参数的类型和数量。SIL中的功能如下所示:

mymethod(myparameter);

因此,{{TypeInst.STRING}}意味着我们将有一个参数,其类型为String。如果要传递String类型的两个参数,则需要像这样更改字符串:

private static final SILType[][] types = {{ TypeInst.STRING, TypeInst.STRING }};

在SIL中,您可以这样调用函数:

mymethod(myparameter1, myparameter2);

如果您的函数可以接受一个或两个参数。该术语将如下所示:

private static final SILType[][] types = {{ TypeInst.STRING},  
                                                          {TypeInst.STRING, TypeInst.STRING }};

接下来是:

public class SayHello extends AbstractSILRoutine<MutableString>

我们从AbstractSILRoutine继承我们的类,这意味着我们的类将返回String类型的参数。

进一步:

public SayHello(ClassLoader classLoader, String name) { 
  super(classLoader, name, types);
}

这是构造函数。您可能不必更改其中的任何内容。

进一步:

@Override 
public SILType<MutableString> getReturnType() { return TypeInst.STRING; }

在这里,我们确定返回参数的类型。在我们的例子中,它是字符串。

进一步:

@Override 
protected SILValue<MutableString> runRoutine(SILContext silContext, List<SILValue<?>> list) { 
SILValue param = list.get(0); 
return SILValueFactory.string( "Hello " + param.toStringValue());
}

这是您功能的主要切入点。在SIL中执行功能时,您将到达此处。所有逻辑都在这里。

该函数有两个参数:

silContext-允许您获取Jira和SIL变量。

例如,您的SIL脚本用作发布功能,并且您希望收到执行该脚本的票证:

Issue issue = (Issue) silContext.getAllMetaInformation().get("issue");

列表-允许您获取传递给SIL函数的参数的值。

SILValue param = list.get(0); 

线:

SILValueFactory.string( "Hello " + param.toStringValue());

返回值。您必须返回SIL可以理解的值,因此请使用SILValueFactory生成值。

进一步:

@Override 
public String getParams() { return "(name)"; }

这定义了SIL Manager中的功能类型。当您开始在SIL管理器中输入内容时,系统会提示您一些可用功能。在我们的案例中,您将看到:

yourmethod(name)

将我们的课程添加到SIL引擎


您已经创建了课程。现在,您需要使SIL意识到您的功能。这是在ESLauncher.java文件中完成的。该文件包含以下几行:

RoutineRegistry.register(new SayHello( classLoader,"SayHello")); 

这一行说,我们将SayHello类添加到SIL下,名称为SayHello。类名和函数可能不匹配。

接下来,添加以下行:

RoutineRegistry.unregister("SayHello");

将SayHello更改为函数的名称。如果您从Jira删除插件,则此行将从SIL卸载功能。

有关SIL的更多信息


在SayHello2类中,我们返回一个List。

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);

为了使它起作用,还需要将返回值更改为TypeInst.STRING_ARR并使用KeyableArraySILObject从AbstractSILRoutine继承。

在SIL中,您可以这样调用SayHello2:

string[] res = SayHello2("Alexey", "Matveev");
runnerLog(res[0]);
runnerLog(res[1]);

在SayHello3中,我们返回Map:

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);

在SIL中,您可以像这样调用SayHello3:

res = SayHello3("Alexey", "Matveev");
runnerLog(res["param1"]);
runnerLog(res["param2"]);

在这种情况下,我们不是通过索引而是通过键来获取数组的元素。

如果您看一下Java中的代码,则在两种情况下我们都将使用KeyableArraySILObject。事实是,在SIL中,List和Map是由KeyableArraySILObject类实现的。那些。SIL中的任何数组都可以通过索引或键来访问。

我们将数组作为参数传递


我们可以从SIL函数返回一个数组。现在,让我们看看如何将数组作为参数传递。

该代码将如下所示:

@Override
protected SILValue<MutableString> runRoutine(SILContext silContext, List<SILValue<?>> list) {
    GenericArraySILObject rowsToUpdate =  (GenericArraySILObject) list.get(0).getObject();
    Map<String, int[]> keys = rowsToUpdate.getKeysMapping()
......
}

首先,我们从参数中获取GenericArraySILObject类的对象,然后从中获取Map。

在SIL中,您可以像这样传递一个数组:

string[] arr;
arr["key1"] = "value1";
arr["key2"] = "value2";
yourmethod(arr);

到此结束本文。我希望您掌握了足够的知识,可以在SIL中编写函数。

All Articles