System
Funkcje ułatwiają wykonywanie często wykonywanych operacji, takich jak np. sumowanie wartości. Zapobiega to wielokrotnej duplikacji kodu. Funkcje powinny być niezależne oraz jak najbardziej ogólne i elastyczne (możliwość wykorzystania ich w jak największej liczbie przypadków).
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 |
FunctionAPIWszystkie 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 serwerzeRejestracja 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 |
---|
property | javadoc.plusworkflow |
---|
className | com.suncode.pwfl.core.function.FunctionRegistry |
---|
| . Podczas rejestracji wyszukiwane są najpierw wszystkie klasy oznaczone adnotacją @ Javadoc |
---|
property | javadoc.plusworkflow |
---|
className | com.suncode.pwfl.core.function.annotation.Functions |
---|
| , następnie w tych klasach wyszukiwane są metody oznaczone adnotacją @ Javadoc |
---|
property | javadoc.plusworkflow |
---|
className | com.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ść |
wyższej większej liczby. Code Block |
---|
language | java |
---|
linenumbers | true |
---|
| @Functions
public class BasicFunctions
{
@Function
public Integer maxOf( Integer a, Integer b )
{
return Math.max( a, b );
}
} |
|
Zarejestrowana funkcja posiada nazwę, zwracany typ oraz definicję parametrów -> 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 |
---|
property | javadoc.plusworkflow |
---|
className | com.suncode.pwfl.core.function.annotation.Function |
---|
| . |
Rejestracja po stronie przeglądarki
Po stronie przeglądarki musimy sami zarejestrować funkcję. W tym celu należy wywołać metodę register z Jsdoc |
---|
property | jsdocParametr jest typu @ Javadoc |
---|
property | javadoc.plusworkflow |
---|
className |
---|
|
|
PWfnFunctionsW tym przypadku zarejestrowaliśmy funkcję (podaną jako drugi parametr) o nazwie maxOf.
Funkcja register zwraca obiekt zarejestrowanej funkcji
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. |
...
var registeredFunction = Functions.register("maxOf", function(a,b){
return Math.max(a,b);
});
| @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 funkcjiKontekst 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 |
---|
| 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ądarkiUż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 |
---|
property | javadoc.plusworkflow |
---|
className | com.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 |
---|
language | java |
---|
linenumbers | true |
---|
| @Functions
@FunctionsScript("/functions/basic-functions.js")
public class BasicFunctions
{
...
} |
Funkcje rejestrowane są z wykorzystaniem API Jsdoc |
---|
property | jsdoc.plusworkflow |
---|
className | PW. |
---|
|
|
core.RegisteredFunction. Możemy na tym obiekcie ustawić typy parametrów wejściowych funkcji za pomocą metody withParameterTypes, gdzie podajemy typy parametrów w takiej samej kolejności jak występują one w funkcji (skrócona nazwa PW.Functions ): |
...
registeredFunction.withParameterTypes(FloatType, FloatType);
Info |
---|
Jeżeli zdefiniowane zostaną typy parametrów funkcji, to podczas wywoływania funkcji podane wartości parametrów są konwertowane do tych typów. |
...
Mając pobraną funkcję z parametrami (
// 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 wtyczceRejestracja 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 |
---|
| <functions key="functions" /> |
|
Jest to wymagane, aby nie trzeba było przeszukiwac wszystkich uruchomionych wtyczek, tylko te, które faktycznie posiadają funkcje.
Wykorzystanie funkcji po stronie przeglądarki
Obecnie funkcje mogą być wykorzystywane na formularzu zadania.
Pobranie funkcji odbywa się za pomocą obiektu
Jsdoc |
---|
property | jsdoc.plusworkflow |
---|
className | PW.core.fn.Functions |
---|
|
: Code Block |
---|
|
var fn = Functions.getFunction("maxOf",[1,4]); |
Taki wpis spowoduje automatyczne wyszukanie wszystkich zdefiniowanych we wtyczce funkcji. Tłumaczenia opisów funkcji i parametrówFunkcje 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 element | Szablon |
---|
Opis funkcji | function.<name>
gdzie | 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 |
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ń funkcjiKaż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 |
---|
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. FunctionAPIAll 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 serverThe 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 |
---|
property | javadoc.plusworkflow |
---|
className | com.suncode.pwfl.core.function.FunctionRegistry |
---|
| . During registration, all classes marked with the annotation @ Javadoc |
---|
property | javadoc.plusworkflow |
---|
className | com.suncode.pwfl.core.function.annotation.Functions |
---|
| , are searched first, then methods marked with the annotation @ Javadoc |
---|
property | javadoc.plusworkflow |
---|
className | com.suncode.pwfl.core.function.annotation.Function |
---|
| are searched in these classes and are registered as functions. The registered function must: The following example shows the definition of a simple function that returns the value of a larger number. Code Block |
---|
language | java |
---|
linenumbers | true |
---|
| @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 |
---|
property | javadoc.plusworkflow |
---|
className | com.suncode.pwfl.core.function.annotation.Function |
---|
| . The parameter of type @ Javadoc |
---|
property | javadoc.plusworkflow |
---|
className | com.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 |
---|
language | java |
---|
linenumbers | true |
---|
| @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 contextThe 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 |
---|
| 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 registrationUsing 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 |
---|
property | javadoc.plusworkflow |
---|
className | com.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 |
---|
language | java |
---|
linenumbers | true |
---|
| @Functions
@FunctionsScript("/functions/basic-functions.js")
public class BasicFunctions
{
...
} |
Functions are registered using the API Jsdoc |
---|
property | jsdoc.plusworkflow |
---|
className | PW. |
---|
|
|
core.Function) możemy ją wywołać (short name PW.Functions): |
...
fn.call(); //returns 4;
// 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 pluginThe 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 |
---|
| <functions key="functions" /> |
This entry will automatically search for all functions defined in the plugin. Translations of function and parameter descriptionsFunctions 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 element | Template |
---|
function description | function.<name>
where | 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 |
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 overloadsEach 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 |
|