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.
Wykorzystanie funkcji możliwe jest w następujących obszarach:
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.
Spis wbudowanych funkcji systemowych dostępny jest na stronie: Spis dostępnych funkcji |
Wszystkie operacje związane z działaniami na funkcjach stanowią FunctionAPI.
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 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 . Podczas rejestracji wyszukiwane są najpierw wszystkie klasy oznaczone adnotacją @
, następnie w tych klasach wyszukiwane są metody oznaczone adnotacją @
i zostają one zarejestrowane jako funkcje.
Rejestrowana funkcja musi składać się z:
Poniższy przykład przedstawia definicję prostej funkcji zwracającej wartość większej liczby.
@Functions public class BasicFunctions { @Function public Integer maxOf( Integer a, Integer b ) { return Math.max( a, b ); } } |
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ę 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:
@Functions @FunctionsScript("/functions/basic-functions.js") public class BasicFunctions { ... } |
Funkcje rejestrowane są z wykorzystaniem API (skrócona nazwa
PW.Functions
):
// 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:
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 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:
<functions key="functions" /> |
Taki wpis spowoduje automatyczne wyszukanie wszystkich zdefiniowanych we wtyczce funkcji.
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ą:
Klucze tłumaczeń funkcji muszą być tworzone z zachowaniem następujących zasad:
Tłumaczony element | Szablon |
---|---|
Opis funkcji |
gdzie
|
Nazwa parametru |
gdzie
|
Opis parametru |
gdzie
|
Przykład:
Dla funkcji zdefiniowanej w następujący sposób:
@Function public boolean isHoliday(LocalDate date) { // implementacja } |
Tłumaczenia wyglądały będą następująco:
function.isHoliday=Sprawdza czy data wskazuje dzień wolny od pracy function.isHoliday.param.date.name=Data function.isHoliday.param.date.desc=Sprawdzana data |
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:
@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:
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 |