= Bonita actor filter archetype
:description: A set of best of breed tools to develop and test custom actor filters independently of the Bonita Studio.

{description}

== Create a custom actor filter

Bonita offers the possibility to create and plug custom actor filters, to allow you to fine tune the potential candidates for a task. +
We provide a maven archetype to help you bootstrap an actor filter project. The source code of the archetype is available https://github.com/bonitasoft/bonita-actorfilter-archetype[here].

=== Prerequisite

. Java 8 must be installed: https://adoptopenjdk.net/index.html
. Maven must be installed: https://maven.apache.org/install.html
. Actor filter development requires some software development skills. The archetype offers the possibility to develop the connector in _Java_, _Groovy_ or _Kotlin_. Make sure that you are comfortable with at least one of those three languages.

=== Generate the project using the maven archetype

A https://maven.apache.org/archetype/index.html[maven archetype] is a maven project templating toolkit. This archetype allows you to bootstrap a Bonita actor filter project on your file system. A Bonita actor filter project is a maven project. It can be built, tested and then imported into a Bonita project using Bonita Studio.

To create your actor filter project, prompt a terminal and enter the following command:

[WARNING]
====
Make sure that you are not executing the command from an existing maven project.
====

[source,bash]
----
mvn archetype:generate -DarchetypeGroupId=org.bonitasoft.archetypes -DarchetypeArtifactId=bonita-actorfilter-archetype -DarchetypeVersion=1.0.0
----

You'll then have to specify interactively the properties of your project:

* *groupId:* the group id of your connector.
* *artifactId:* the artifact id of your filter
 ** Must match the following regex: `+^[a-zA-Z0-9\-]+$+`
 ** Example: _my-custom-filter_
* *version:* the version of your connector _(default value: 1.0-SNAPSHOT)_
Follow the http://maven.apache.org/guides/mini/guide-naming-conventions.html[maven naming convention guide]
* *package* the package in which the source files will be created _(default value: the group id of the connector)_
* *bonitaVersion:* the targeted Bonita version
 ** A Bonita actor filter project depends on _org.bonitasoft.engine:bonita-common_. To avoid potential conflicts / errors at runtime, you should use the Bonita version of your runtime environment.
* *className:* the class name of your actor filter
 ** Must match the following regex: `+^[a-zA-Z_$][a-zA-Z\d_$]+$+` (A Java classname valid identifier)
 ** Example: _MyCustomFilter_
* *language*: the language used in the connector project. Available values:
 ** java
 ** groovy
 ** kotlin
* *wrapper* _(optional)_: install a https://github.com/takari/maven-wrapper[Maven wrapper, window = "_blank"]. Available values:
 ** true _(default)_
 ** false

A folder named _[your artifact id]_ is created, with your Bonita actor filter project, ready to use.

[WARNING]
====
You can avoid the interactive mode by specifying all properties of your project directly in the command line, but by doing that you'll bypass the validation performed on the properties content.
====

=== Actor filter development

In this section we'll look into the different components of an actor filter project, and how you should use them to develop your filter.

==== Definition

An actor filter is first defined by its *definition*.  It is an XML file located in _src/main/resources-filtered/[artifactId].def_ by default. +
A definition defines the inputs of an actor filter. It can be seen as a contract. Then, implementations of this definition can be created, they just need to respect the inputs contract of the definition.

The connector definition XSD is available in _schemas/connector-definition-descriptor.xsd_ (it is the same for definition model for Connectors and Actor filters definitions), you can import it in a IDE to get completion.

image::images/connector-def-xsd-overview.png[Connector definition xsd overview]

Example:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<definition:ConnectorDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:definition="http://www.bonitasoft.org/ns/connector/definition/6.1">
    <id>${definition-id}</id> <!-- Id of the definition -->
    <version>${definition-version}</version> <!-- Version of the definition -->
    <icon>icon.png</icon> <!-- The icon used in the Studio for this definition -->
    <category icon="icon.png" id="Custom"/> <!-- The category of this definition, used in the Studio (e.g: http, script ...) -->

    <!-- Connector inputs -->
    <input mandatory="true" name="defaultInput" type="java.lang.String"/>

    <!--
       Pages and widgets to use the connector in the Bonita Studio.
       - Each widget must be bound to an input
       - Page titles must be defined in the properties files
       - Widget labels must be defined in the properties files
       - Page and widget descriptions can be defined in the properties files (optional)
    -->
    <page id="defaultPage">
        <widget xsi:type="definition:Text" id="defaultInputWidget" inputName="defaultInput"/>
    </page>

</definition:ConnectorDefinition>
----

`definition-id` and `definition-version` are properties defined in the `pom.xml`.

===== Actor filter Inputs

The inputs of an actor filter are defined in the definition. Those inputs are valued by processes, and are retrieved by the implementation classes of the actor filter to execute the business logic. +
A actor filter input:

* Has a name
* Has a type
* Has an optional default value
* Can be mandatory

===== Pages and widgets

A definition includes _pages_ and _widgets_.  Those elements define the UI that will appear in the Bonita Studio to configure the actor filter.

* A widget is bound to an input
* A page contains a set of widgets

The idea is to create pages for related inputs, so the person who will configure the actor filter will easily understand what he has to do.

All the available widgets are defined in the XSD. You must reference the widget type in the tag to create a specific widget:

[source,xml]
----
<widget  xsi:type="definition:[WIDGET TYPE]"  id="[WIDGET ID]"  inputName="[CORRESPONDING INPUT]"/>
----

The widget id is used in the _.properties_ files to define and translate the widget name and the widget description. +
The input name is used to bind this widget to one of the connector inputs.

Some widgets can require additional informations. For example, if you want to create a select widget with a set of item to select, you will have to do something like that:

[source,xml]
----
<widget xsi:type="definition:Select" id="choiceWidget" inputName="choice">
    <items>Choice 1</items>
    <items>Choice 2</items>
    <items>Choice 3</items>
</widget>
----

===== Add multiple definitions

To add a new definition create a `.def` file in the `src/main/resources-filtered/` folder. They will be added to `all` zip archive at build time. It is recommended to use the maven properties for definition id and version.


==== Actor filter implementation

An _actor filter implementation_ implements a definition. A definition defines a set of inputs, implementing a definition means use the provided inputs to create the expected list of users ids. +
Several implementations can be created for a given definition.

An actor filter implementation is made of two elements:

* An xml file used to explicit the definition implemented, the dependencies required and the name of the implementation class
* A set of Java based classes, constituting the implementation sources

===== Implementation XML file

The implementation XML file is located in _src/main/resources-filtered/[artifactId].impl_ by default. +
The implementation XSD is available in _schemas/connector-implementation-descriptor.xsd_, you can import it in a IDE to get completion.

image::images/connector-impl-xsd-overview.png[Connector implementation xsd overview]

Example:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<implementation:connectorImplementation xmlns:implementation="http://www.bonitasoft.org/ns/connector/implementation/6.0">
  <implementationId>${impl-id}</implementationId> <!-- Id of the implementation -->
  <implementationVersion>${impl-version}</implementationVersion> <!-- Version of the implementation -->
  <definitionId>${definition-id}</definitionId> <!-- Id of the definition implemented -->
  <definitionVersion>${definition-version}</definitionVersion> <!-- Version of the definition implemented -->
  <implementationClassname>${impl-main-class}</implementationClassname> <!-- Path to the main implementation class -->
  <description>Default ${definition-id} implementation</description>

<!-- retrieved from the pom.xml at build time -->
${impl-dependencies}

</implementation:connectorImplementation>
----

`impl-id`, `impl-version`, `definition-id`, `definition-version` and `impl-main-class` are properties defined in the `pom.xml`. +
`impl-dependencies` is replaced at build time using `src\script\dependencies-as-var.groovy` script.

===== Implementation sources

The implementation sources contain all the logic of the actor filter:

* The validation of the inputs
* The execution of the business logic to filter the users for a given actor.

The archetype offers the possibility to generate the default sources in Java, Groovy or Kotlin. The build result will always be a Java archive (jar) and some Zip archives (assemblies), no matters the language selected.

The entry point of the implementation sources must extend the https://javadoc.bonitasoft.com/api/{javadocVersion}/org/bonitasoft/engine/filter/AbstractUserFilter.html[__AbstractUserFilter__, window="_blank"] class
or implement https://javadoc.bonitasoft.com/api/{javadocVersion}/org/bonitasoft/engine/filter/UserFilter.html[__UserFilter__, window="_blank"] interface.

===== Add multiple implementations

To add a new implementation create a `.impl` file in the `src/main/resources-filtered/` folder. They will be added to the `all` zip archive at build time. It is recommended to use the Maven properties for implementation id and version.

==== Build the project

Build the project by typing the following command at the root of the project:

[source,bash]
----
./mvnw clean install
----

A actor filter project is built using Maven, and especially the https://maven.apache.org/plugins/maven-assembly-plugin/[maven assembly plugin].

The default build output is:

*  `target/[artifact id]-[artifact version]-all.zip` : By importing this archive in a Bonita Studio you will import all the definitions and implementations created in the project.
*  `target/[artifact id]-[artifact version]-impl.zip` : An archive containing a single implementation.
