Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Polish

Table of Contents
outlinetrue
stylenone

Funkcje pozwalają na deklaratywne przetwarzanie danych bez konieczności pisania własnego kodu. Rozwiązanie to opiera się na wywoływaniu wybranej funkcji (użytkownicy mogą dostarczać własne specyficzne implementacje) i przekazaniu wyniku tej funkcji dalej np. do zadania automatycznego. W przypadku podstawowych działań matematycznych, kwotowych, tekstowych czy logicznych możliwe jest zrealizowanie prostych przekształceń bez napisania linijki kodu.

 

Tworzone funkcje powinny być ja najbardziej ogólne i elastyczne. Pozwoli to na wykorzystanie ich w większej liczbie przypadków. System pozwala na rejestrowanie i wykorzystywanie predefiniowanych funkcji zarówno po stronie serwera jak i po stronie przeglądarki.

Tip

Spis wbudowanych funkcji systemowych dostępny jest na stronie: Dostępne funkcje

FunctionAPI

Wszystkie operacje związane z działaniami na funkcjach stanowią FunctionAPI.

Info
 W tworzonych funkcjach po stronie przeglądarki wspierany jest standard ECMAScript 6.

Rejestracja funkcji

Note
Funkcja musi zawsze być zarejestrowana po stronie serwera oraz może dodatkowo być zarejestrowana po stronie przeglądarki, gdy chcemy, aby była też tam wykorzystywana.

Rejestracja na serwerze

Rejestracja funkcji dostępnych w systemie odbywa się podczas uruchomienia systemu oraz dynamicznie dla dynamicznych zasobów, takich jak wtyczki. Za rejestrację i przechowywanie funkcji odpowiada 

Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.FunctionRegistry
. Podczas rejestracji wyszukiwane są najpierw wszystkie klasy oznaczone adnotacją @
Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.annotation.Functions
, następnie w tych klasach wyszukiwane są metody oznaczone adnotacją @
Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.annotation.Function
 i zostają one zarejestrowane jako funkcje.

 

Rejestrowana funkcja  musi:

Poniższy przykład przedstawia definicję prostej funkcji zwracającej wartość większej liczby.

Code Block
languagejava
linenumberstrue
@Functions
public class BasicFunctions
{
    @Function
    public Integer maxOf( Integer a, Integer b )
    {
        return Math.max( a, b );
    }
}

Można określić, czy funkcja dotyczy tylko serwera (można jej użyć tylko na serwerze), czy tylko przeglądarki (można jej użyć tylko w javascript), czy obu miejsc. Odpowiada za to parametr accessibility, który można ustawić w adnotacji @

Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.annotation.Function
. Parametr jest typu @
Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.Function.FunctionAccessibility
 i może przyjmować następujące wartości:

  • SERVER -  funkcji nie można wykorzystać w javascript, czyli np. w akcjach (nie jest w ogóle pokazywana dla akcji w PWE w liście z funkcjami do wyboru), natomiast można ją użyć w pozostałych typach komponentów, czyli wykonywanych na serwerze.
  • BROWSER -  funkcję można wykorzystać w javascript, czyli np. w akcjach, natomiast można jej użyć w pozostałych typach komponentów, czyli wykonywanych na serwerze (nie jest w ogóle pokazywana dla tych komponentów w PWE w liście z funkcjami do wyboru).
  • ALL - funkcja może być używana wszędzie. Jest to wartość domyślna parametru.

Brak ustawionego parametru accessibility odpowiada wartości ALL.

Poniższy przykład pokazuje definicję funkcji, która jest dostępna tylko dla komponentów serwerowych. Funkcja zwraca imię i nazwisko użytkownika na podstawie jego loginu.

Code Block
languagejava
linenumberstrue
@Functions
public class BasicFunctions
{
    @Function( accessibility = FunctionAccessibility.SERVER )
    public String userFullName( String userName )
    {
        User user = userService.getUser( userName );
        if ( user == null )
        {
            return null;
        }
        return user.getFullName();
    }
}

Jeżeli robimy funkcję tylko dla przeglądarki, to na serwerze również musi być funkcja zdefiniowana, ale jej implementacja nie musi nic robić. Służyć ona ma tylko do pobrania nazwy i parametrów funkcji i wyświetlania jej w PWE.

Kontekst funkcji

Kontekst funkcji zawiera identyfikator oraz definicję aktualnie przetwarzanego procesu i zadania. Pobranie kontekstu możliwe jest tylko po stronie serwera za pomocą poniższego kodu.

Code Block
languagejava
FunctionContext context = FunctionContext.current(); // statyczne pobranie kontekstu
 
String processId = context.getProcessId(); // id procesu
String activityId = context.getActivityId(); // id zadania
String processDefId = context.getProcessDefId(); // id definicji procesu
String activityDefId = context.getActivityDefId(); // id definicji zadania

Rejestracja po stronie przeglądarki

Używanie stworzonej funkcji po stronie przeglądarki (na formularzu zadania) wymaga od programisty dostarczenia jej implementacji w języku JavaScript. Taka implementacja wykorzystywana jest podczas dynamicznych obliczeń po stronie przeglądarki klienta.

W przypadku funkcji z implementacją JavaScript należy dodatkowo wskazać poprzez adnotację 

Javadoc
displayValue@FunctionsScript
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.annotation.FunctionsScript
 gdzie znajduje się skrypt, który zawiera implementacje tych funkcji. Należy wskazać bezwzględną ścieżkę do zasobu w classpath. Zasób przechowywany w src/main/resources/functions/basic-functions.js wskażemy tak:

Code Block
languagejava
linenumberstrue
@Functions
@FunctionsScript("/functions/basic-functions.js")
public class BasicFunctions
{
    ...
}

Funkcje rejestrowane są z wykorzystaniem API 

Jsdoc
propertyjsdoc.plusworkflow
classNamePW.fn.Functions
 (skrócona nazwa PW.Functions):

Code Block
languagejs
// funkcja "max" która zwraca obiekt typu "float" i przyjmuje 2 parametry typu "float"
PW.Functions.register("max", "float", ["float", "float"], function(value1, value2){
	return Math.max(value1, value2);
});
 
// funkcja "upper" która zwraca obiekt typu "string" i przyjmuje 1 parametry typu "string"
PW.Functions.register("upper", "string", ["string"], function(text){
	return text.toUpperCase();
});

Podczas rejestracji funkcji niezbędne jest zdefiniowanie:

  • nazwy (można zarejestrować wiele funkcji o tej samej nazwie ale musza mieć one inne typy parametrów)
  • typu zwracanej wartości
  • typów parametrów
  • implementacji funkcji

Tak zarejestrowana funkcja zostanie wywołana tylko dla wywołań z argumentami które będą pasowały do zdefiniowanych typów. Możliwe typy opisane są w Wbudowane typy.

Rejestracja we wtyczce

Rejestracja funkcji we wtyczce jest taka sama jak zostało to opisane powyżej, jednak należy dodatkowo zaznaczyć, że wtyczka ta udostępnia funkcje do zarejestrowania. W tym celu należy w pliku suncode-plugin.xml dodać wpis:

Code Block
languagexml
<functions key="functions" />

Taki wpis spowoduje automatyczne wyszukanie wszystkich zdefiniowanych we wtyczce funkcji.

Tłumaczenia opisów funkcji i parametrów

Funkcje tłumaczone są automatycznie, jeżeli dostępne są tłumaczenia funkcji stworzone z wykorzystaniem mechanizmu internacjonalizacji. Poniżej opisano zasady tworzenia kluczy tłumaczeń.

Tłumaczeniu podlegają:

  • opis funkcji
  • nazwy parametrów
  • opisy parametrów

Klucze tłumaczeń funkcji muszą być tworzone z zachowaniem następujących zasad:

Tłumaczony elementSzablon
Opis funkcji

function.<name>

gdzie

  • <name> - nazwa funkcji
Nazwa parametru

function.<name>.param.<paramName>.name

gdzie

  • <name> - nazwa funkcji
  • <paramName> nazwa parametru
Opis parametru

function.<name>.param.<paramName>.desc

gdzie

  • <name> - nazwa funkcji
  • <paramName> nazwa parametru
Opis dla przestarzałej funkcji

function.<name>.deprecated.description

gdzie

  • <name> - nazwa funkcji

Przykład:

Dla funkcji zdefiniowanej w następujący sposób:

Code Block
@Function
public boolean isHoliday(LocalDate date) {
	// implementacja
}

Tłumaczenia wyglądały będą następująco:

Code Block
function.isHoliday=Sprawdza czy data wskazuje dzień wolny od pracy
function.isHoliday.param.date.name=Data
function.isHoliday.param.date.desc=Sprawdzana data

Dla przestarzałej funkcji zdefiniowanej w następujący sposób:

Code Block
@Function
@Deprecated
public boolean isHoliday(LocalDate date) {
	// implementacja
}

Tłumaczenia wyglądały będą następująco:

Code Block
function.isHoliday=Sprawdza czy data wskazuje dzień wolny od pracy
function.isHoliday.param.date.name=Data
function.isHoliday.param.date.desc=Sprawdzana data
function.isHoliday.deprecated.description=Funkcja jest przestarzała i należy korzystać z funkcji isHoliday(LocalDate date, Locale locale)

Tłumaczenie przeciążeń funkcji

Każda funkcja może mieć wiele przeciążeń, które przyjmują inne parametry. Może istnieć potrzeba nadania innych opisów dla tych parametrów lub innego opisu funkcji. Jest to możliwe poprzez dodanie do nazwy funkcji wykorzystywanej w kluczu tłumaczenia typów parametrów rozdzielonych podkreślnikiem (_). Domyślnym tłumaczeniem jest to bez typów parametrów.

Nazwy typów dostępne są tutaj: Wbudowane typy

Przykład:

Dla funkcji zdefiniowanej w następujący sposób:

Code Block
@Function
public boolean isHoliday(LocalDate date) {
	// implementacja
}
 
@Function
public boolean isHoliday(LocalDate[] dates) {
	// implementacja
}
 
@Function
public boolean isHoliday(LocalDate[] dates, boolean all) {
	// implementacja
}

Tłumaczenia wyglądały będą następująco:

Code Block
function.isHoliday=Sprawdza czy data wskazuje dzień wolny od pracy
function.isHoliday.param.date.name=Data
function.isHoliday.param.date.desc=Sprawdzana data
 
function.isHoliday_date[]=Sprawdza czy wszystkie podane daty to dni wolne od pracy
function.isHoliday_date[].param.dates.name=Daty
function.isHoliday_date[].param.dates.desc=Sprawdzane daty
 
function.isHoliday_date[]_boolean=Sprawdza czy podane daty to dni wolne od pracy
function.isHoliday_date[]_boolean.param.dates.name=Daty
function.isHoliday_date[]_boolean.param.dates.desc=Sprawdzane daty
function.isHoliday_date[]_boolean.param.all.name=Wszystkie
function.isHoliday_date[]_boolean.param.all.desc=Zaznacz jeżeli chcesz aby wszystkie daty były dniami wolnymi od pracy

 

 

English

Table of Contents
outlinetrue
stylenone

Functions allow declarative processing of data without writing custom code. The solution is based on calling a selected function (users can provide their own specific implementations) and passing the result of this function on to, for example, an automated task. In the case of basic mathematical, quotient, textual or logical operations, it is possible to realize simple transformations without writing a line of code.

 

The functions created should be as general and flexible as possible. This will allow them to be used in more cases. The system allows you to register and use predefined functions both on the server side and on the browser side.

Tip

An list of built-in system functions is available on the site:

Available functions

FunctionAPI

All operations related to actions on functions represent FunctionAPI.

Info
The ECMAScript 6 standard is supported in the functions created on the browser side.

Function registration

Note
The function must always be registered on the server side and can additionally be registered on the browser side when you want it to be used there as well.

Registration on the server

The registration of functions available in the system is done at system startup and dynamically for dynamic resources such as plugins. The registration and storage of functions is the responsibility of 

Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.FunctionRegistry
. During registration, all classes marked with the annotation @
Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.annotation.Functions
, are searched first, then methods marked with the annotation @
Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.annotation.Function
are searched in these classes and are registered as functions.

 

The registered function must:

  • return a value basic type
  • define 0 or many parameters of a basic type

  • be stateless - it should not store state between calls

The following example shows the definition of a simple function that returns the value of a larger number.

Code Block
languagejava
linenumberstrue
@Functions
public class BasicFunctions
{
    @Function
    public Integer maxOf( Integer a, Integer b )
    {
        return Math.max( a, b );
    }
}

You can specify whether the function applies only to the server (can be used only on the server), only to the browser (can be used only in javascript), or both places. The accessibility parameter, which can be set in the annotation @

Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.annotation.Function
. The parameter of type @
Javadoc
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.Function.FunctionAccessibility
and can take the following values:

  • SERVER -  the function cannot be used in javascript, i.e. for example in actions (it is not shown at all for actions in PWE in the list with selectable functions), while it can be used in other types of components, i.e. executed on the server.
  • BROWSER -  the function can be used in javascript, i.e. in actions, for example, while it can be used in other types of components, i.e. executed on the server (it is not shown at all for these components in PWE in the list with selectable functions).
  • ALL - the function can be used anywhere. This is the default value of the parameter.

No accessibility parameter set corresponds to the value of ALL.

The following example shows the definition of a function that is available only to server components. The function returns the name of the user based on his login.

Code Block
languagejava
linenumberstrue
@Functions
public class BasicFunctions
{
    @Function( accessibility = FunctionAccessibility.SERVER )
    public String userFullName( String userName )
    {
        User user = userService.getUser( userName );
        if ( user == null )
        {
            return null;
        }
        return user.getFullName();
    }
}

If the function is created for the browser then there must also be a function defined on the server, but its implementation does not have to do anything. It is only to retrieve the name and parameters of the function and display it in the PWE.

Function context

The function context contains the identifier and definition of the currently processed process and task. Retrieving the context is possible only on the server side using the following code.

Code Block
languagejava
FunctionContext context = FunctionContext.current(); // statyczne pobranie kontekstu
 
String processId = context.getProcessId(); // process id
String activityId = context.getActivityId(); // task id 
String processDefId = context.getProcessDefId(); // process definition id
String activityDefId = context.getActivityDefId(); // task definition id

Browser-side registration

Using the created function on the browser side (on the task form) requires the programmer to provide its implementation in JavaScript. Such an implementation is used during dynamic calculations on the client's browser side.

In the case of functions with JavaScript implementations, you must additionally indicate by annotation

Javadoc
displayValue@FunctionsScript
propertyjavadoc.plusworkflow
classNamecom.suncode.pwfl.core.function.annotation.FunctionsScript
where the script that contains the implementations of these functions is located. The absolute path to the resource in classpath should be indicated. A resource stored in src/main/resources/functions/basic-functions.js would be indicated like this:

Code Block
languagejava
linenumberstrue
@Functions
@FunctionsScript("/functions/basic-functions.js")
public class BasicFunctions
{
    ...
}

Functions are registered using the API 

Jsdoc
propertyjsdoc.plusworkflow
classNamePW.fn.Functions
(short name PW.Functions):

Code Block
languagejs
// function "max" which returns an object of type "float" and takes 2 parameters of type "float"
PW.Functions.register("max", "float", ["float", "float"], function(value1, value2){
	return Math.max(value1, value2);
});
 
// function "upper" which returns an object of type "string" and accepts 1 parameters of type "string"
PW.Functions.register("upper", "string", ["string"], function(text){
	return text.toUpperCase();
});

When registering a function, it is necessary to define:

  • the name (you can register multiple functions with the same name but they must have different parameter types)
  • the type of the returned value
  • types of parameters
  • implementation of the function

A function registered in this way will be called only for calls with arguments that match the defined types. The possible types are described in Build-in types.

Registration in the plugin

The registration of functions in the plugin is the same as described above, but it should be noted in addition that the plugin provides functions to be registered. To do this, add an entry in the suncode-plugin.xml file:

Code Block
languagexml
<functions key="functions" />

This entry will automatically search for all functions defined in the plugin.

Translations of function and parameter descriptions

Functions are translated automatically if function translations created using the internationalization mechanism are available. The rules for creating translation keys are described below.

Subject of translation:

  • function description
  • parameter names
  • parameter descriptions

Translation keys of functions must be created with the following rules:

Translated elementTemplate
function description

function.<name>

where

  • <name> - function name
parameter names

function.<name>.param.<paramName>.name

where

  • <name> - function name
  • <paramName> parameter name

parameter descriptions

function.<name>.param.<paramName>.desc

where

  • <name> - function name
  • <paramName> parameter name
description for the obsolete function

function.<name>.deprecated.description

where

  • <name> - function name

Example:

For a function defined as follows:

Code Block
@Function
public boolean isHoliday(LocalDate date) {
	// implementation
}

The translations will be as follows:

Code Block
function.isHoliday=Checks if the date indicates a holiday
function.isHoliday.param.date.name=Date
function.isHoliday.param.date.desc=Checked date

For an obsolete function defined as follows:

Code Block
@Function
@Deprecated
public boolean isHoliday(LocalDate date) {
	// implementation
}

Translations will be as follows:

Code Block
function.isHoliday=Checks if the date indicates a holiday
function.isHoliday.param.date.name=Date
function.isHoliday.param.date.desc=Checked date
function.isHoliday.deprecated.description=This function is obsolete and you should use isHoliday(LocalDate date, Locale locale)

Translation of function overloads

Each function may have multiple overloads that take different parameters. You may need to give different descriptions for these parameters or a different function description. This is possible by adding parameter types separated by an underscore (_) to the function name used in the translation key. The default translation is this without parameter types.

The names of the types are available here: Built-in types

Example:

For a function defined as follows:

Code Block
@Function
public boolean isHoliday(LocalDate date) {
	// implementation
}
 
@Function
public boolean isHoliday(LocalDate[] dates) {
	// implementation
}
 
@Function
public boolean isHoliday(LocalDate[] dates, boolean all) {
	// implementation
}

The translations will be as follows:

Code Block
function.isHoliday=Checks if the date indicates a holiday
function.isHoliday.param.date.name=Date
function.isHoliday.param.date.desc=Checked date
 
function.isHoliday_date[]=Checks if all specified dates are public holidays
function.isHoliday_date[].param.dates.name=Dates
function.isHoliday_date[].param.dates.desc=Checked dates
 
function.isHoliday_date[]_boolean=Checks if the specified dates are holidays
function.isHoliday_date[]_boolean.param.dates.name=Dates
function.isHoliday_date[]_boolean.param.dates.desc=Cheched dates
function.isHoliday_date[]_boolean.param.all.name=All
function.isHoliday_date[]_boolean.param.all.desc=Check if you want all dates to be holidays