Przydatne linki
Źródła danych
Źródła danych to komponenty umożliwiające dokonywanie operacji na danych, takich jak odczyt danych, zapis, usuwanie lub modyfikacja. Źródłem danych może być tabela w bazie danych, zapytanie do bazy danych, plik na dysku, webservice, itp.
Źródła danych nie komponentami samowystarczalnymi, tak jak inne komponenty. Mogą one natomiast być wykorzystywane w innych komponentach. Dla przykładu może to być Datachooser, który wyświetla dane wybranego źródła danych.
Definiowanie źródła danych
Źródła danych tworzone są w oparciu o ich definicję stworzoną przez użytkownika. Definicja taka musi zawierać następujące elementy:
- Adnotację @DataSource (jeżeli źródło danych nie jest definiowane we wtyczce, musi ona pochodzić z pakietu
com.suncode
) - Publiczną metodę oznaczoną adnotacją @Define z jednym parametrem DataSourceDefinitionBuilder
- Publiczną metodę o nazwie datasource, która odpowiada za zwrócenie implementacji DataSourceInstance z logiką źródła danych.
- (opcjonalnie) Publiczną metodę o nazwie validator, która odpowiada za zwrócenie implementacji DataSourceValidator z logiką walidacji deklaracji źródła danych.
Definicja może zawierać również adnotację @DataSourceScript. Adnotacja ta przekazuje ścieżkę do skryptu (z classpath) zawierającego definicję formularza dynamicznego.
Można również przekazać ścieżkę do skryptów, które chcemy użyć na formularzu. W tym celu należy użyć adnotacji @DataSourceInjectScript. Można przekazać ścieżki do wielu skruptów podajęc je w formie @DataSourceInjectScript({skryptPath1, skryptPath2, ..})
Źródło danych może również dostarczać skrypt, który buduje wygląd parametrów podczas jego definiowania w PWE. W tym celu należy dodać kolejną adnotację dla klasy @ComponentsFormScript z przekazaną ścieżką do skryptu (z classpath).
Przykładowa definicja przedstawiona jest poniżej.
@DataSource @DataSourceScript("js/datasource.js") @ComponentsFormScript( "path/example-form.js" ) public class DataSourceExample { @Define public void definition( DataSourceDefinitionBuilder builder ) { builder .id( "example-datasource" ) .name( "datasource.example" ) .description( "datasource.example.desc" ) .category( Categories.TEST ) .operations( DataSourceOperation.READ ) .parameter() .id( "tableName" ) .name( "datasource.parameter.tableName.name" ) .description( "datasource.parameter.tableName.desc" ) .type( Types.STRING) .create(); } public DataSourceInstance datasource( @Param String tableName ) { return new DatabaseTableSource( tableName ); } public DataSourceValidator validator() { return new TableSourceValidator(); } }
Implementacja źródła danych
Źródło danych musi posiadać metodę o nazwie datasource. Metoda może posiadać następujące typy parametrów:
- pojedynczy parametr źródłą danych - typ parametru musi być zgodny ze zdefiniowanym typem oraz musi być poprzedzony adnotacją @Param,
- parametr mapujący dwa parametry tablicowe (klucz, wartość) - typ parametru musi być typu java.util.Map<K,V>, gdzie K to zdefiniowany typ parametru komponentu będącego kluczem, a V to zdefiniowany typ parametru komponentu będącego wartością dla klucza. Parametr musi być oznaczony adnotacją PairedParam ze zdefiniowanymi właściwościami (key - id parametry będącego kluczem, value - id parametru będącego wartością).
- pojedynczy parametr typu DataSourceInstance oznaczony adnotacją @Param - jeżeli posiadamy taki typ, to wstrzyknięty zostanie obiekt DataSourceInstance na podstawie wartości tego parametru, która musi być id źródła danych.
- Parameters - zawiera wszystkie zdefiniowane parametry walidatora wraz z ich wartościami, jest to alternatywa dla pobierania parametru za pomocą wyżej wspomnianej adnotacji@Param,
- Translator - translator dla tego komponentu, więcej informacji tutaj,
- UserInfo - obiekt zawierający informacje na temat użytkownika wykorzystującego źródło danych.
Metoda ta musi zwracać obiekt implementujący interfejs DataSourceInstance. Tak naprawdę ta implementacja powinna rozszerzać abstrakcyjną klasę AbstractDataSourceInstance, aby w przyszłości nie było błędów kompilacji, jeżeli będą dochodzić jakieś nowe metody do interfejsu DataSourceInstance.
Przykład implementacji:
public class DatabaseTableSource extends AbstractDataSourceInstance { private String tableName; public DatabaseTableSource( String tableName ) { this.tableName = tableName; } @Override public CountedResult<Map<String, Object>> getCountedData() { return new CountedResult<Map<String, Object>>(0, Maps.newHashMap()) } @Override public void save( Map<String, Object> data ) { } @Override public void update( Object key, Map<String, Object> data ) { } @Override public void delete( Object key ) { } }
Implementacja nie musi implementować wszystkich metod. Wymagane jest tylko pobieranie danych, gdyż nie każde źródło musi obsługiwać wszystkie operacji na danych.
Walidacja źródła danych
Źródło danych może opcjonalnie posiadać metodę o nazwie validator.
Metoda:
- jest bezparametrowa,
- zwraca obiekt implementujący interfejs DataSourceValidator,
- zwracany obiekt powinien rzucać wyjątek DataSourceValidateException w przypadku niepoprawnej deklaracji źródła danych.
Walidator jest wykorzystywany przy zapisie (utworzenie i aktualizacja) źródła danych.
Przykład implementacji:
public class TableSourceValidator implements DataSourceValidator { @Override public void validate( DataSourceDeclaration declaration ) { ParameterDeclaration someParam = declaration.getParameter( "someParam" ); if ( !someParam.isArray() ) { return; } ParameterValue someValue = someParam.getValue(); if ( someValue.getValue().equals( "zła wartość" ) ) { throw new DataSourceValidateException( "Wartość jest nieprawidłowa" ); } } }
Rejestracja źródła danych we wtyczce
Jeżeli źródło danych jest definiowane we wtyczce to należy dodatkowo zaznaczyć, że wtyczka ta udostępnia komponenty. W tym celu należy w pliku suncode-plugin.xml dodać wpis:
<!-- Udostępnianie zadań autoamtycznych--> <workflow-components key="components" />
Dynamiczny formularz
Dynamiczny formularz umożliwia zdefiniowanie formularza parametrów.
Rejestracja dynamicznego formularza
PW.DataSources.register('system-database-with-build-param', { // Identyfikator źródła danych buildParams: function(form){ // funkcja `buildParam`, która zostanie wykorzystana do zbudowania formularza parametrów źródła danych form.addField('param-1'); form.addTextAreaField('param-2'); form.addCombobox({ id : 'param-3', values : [{id : 'activity', display : 'Activity'}, {id : 'stage', display : 'Stage'}, {id : 'process', display : 'Process'}] }); form.addTable(['param-4', 'param-5', 'param-6'], { tableId: 'fieldMap', name: 'Grupa', description: 'Grupa pól' }); } });
Jeżeli podczas dodawania elementu do formularza zdefiniujemy mu id i ta wartość będzie odnośić się do id parametru zdefiniowanego w komponencie, to wszystkie właściwości dla pola zostaną odczytane z definicji parametru (nazwa, opis, wymagalność, typ).
Jeżeli natomiast chcemy dodać pole, które nie jest związane z żadnym parametrem (nie będzie ono zapisane w deklaracji źródła), to powinniśmy określić nazwę, opis, typ oraz wymagalność.
Dostępne funkcję dynamicznego formularza
Funkcja | Parametry | Opis |
---|---|---|
addField(definition, [position]) | definition - identyfikator dodawanego parametru lub obiekt zawierający definicję pola position - pozycja na której dodany mam zostać parametr. Gdy position nie zostanie podany, parametr zostanie dodany na końcu formularza. | Dodanie parametru. Przykład: ... form.addField('param-1'); ... Jeżeli dodajemy pole niezwiązane z parametrem komponentu, to możemy określić jakiego typu ma być to pole. Dostępne są następujące typy: string, integer, float, date, datetime, boolean. ... form.addField({ id: 'custom', type: 'date', ... }); ... |
addTextArea(definition, [position]) | definition - identyfikator dodawanego parametru lub obiekt zawierający definicję pola position - pozycja na której dodany mam zostać parametr. Gdy position nie zostanie podany, parametr zostanie dodany na końcu formularza. | Dodanie parametru jako pole typu `TextArea`. Parametr musi być typu String.
Przykład: ... form.addTextArea('param-1'); ... lub ... form.addTextArea({ id: 'param-1', ... }); ... |
addCombobox(definition, [position]) | definition - obiekt zawierający definicję pola Definicja powinna zawierać nastepujące pola:
position - pozycja na której dodany mam zostać parametr. Gdy position nie zostanie podany, parametr zostanie dodany na końcu formularza
| Dodanie parametru jako pole typu `Combobox`. Przykład dodanie pola typu 'Combobox' lokalnego (local): ... form.addCombobox({ id: 'param-1', valueField: 'id', displayField: 'display', fields: [ {name: 'id', type: 'string'}, {name: 'display', type: 'string'} ], values : [{id : 'activity', display : 'Zadanie'}, {id : 'stage', display : 'Etap'}, {id : 'process', display : 'Proces'}], sort: [{ property: 'display', direction: 'DESC' }], onChange: function(combo, newValue, oldValue){ ... } }); ... Przykład dodanie pola typu 'Combobox' zdalnego (remote): ... form.addCombobox({ id: 'param-1', valueField: 'id', displayField: 'display', fields: [ {name: 'id', type: 'string'}, {name: 'display', type: 'string'} ], remote: { url: Suncode.getAbsolutePath('plugin/com.suncode.example-plugin/example-combo/get'), remoteSort: false, pageSize: 20 }, sort: [{ property: 'display', direction: 'DESC' }], onChange: function(combo, newValue, oldValue){ ... } }); ... |
addCheckbox(definition, [position]) | definition - identyfikator dodawanego parametru lub obiekt zawierający definicję pola position - pozycja na której dodany mam zostać parametr. Gdy position nie zostanie podany, parametr zostanie dodany na końcu formularza. | Przykład: ... form.addCheckbox('param-1'); ... Jeżeli podpinamy to pod parametr komponentu, to typ tego parametru musi być boolean. |
addTable( [definition] ) | definition - podstawowa definicja tabeli z parametrami. Zawiera następujące pola:
| Dodaje i zwraca "pustą" tabelę ze zgrupowanymi parametrami. Zwrócony obiekt tabeli umożliwia dodanie do niego pól. Przykład: var table = form.addTable(); table.addField('param-1'); table.addField('param-2'); table.addCombobox(...);
|
addRow( [definition] ) | definition - definicja wiersza. Zawiera następujące pola:
| Dodaje i zwraca "pusty" wiersz. Zwrócony wiersz umożliwia dodanie do niego pol. Pola będą dodawane obok siebie. Przykład: var row = form.addRow(); row.addField('param-1'); row.addField('param-2'); row.addCombobox(...); |
addButton(definition, [position] ) | definition - definicja przycisku.
position - pozycja na której dodany mam zostać parametr. Gdy position nie zostanie podany, parametr zostanie dodany na końcu formularza | Dodanie przycisku na formularzu. Przykład: form.addButton({ id: 'btn-1', text: 'Przycisk', handler: function(){ ... } }) |
addPassword(definition, [position] ) | definition - identyfikator dodawanego parametru lub obiekt zawierający definicję pola position - pozycja na której dodany mam zostać parametr. Gdy position nie zostanie podany, parametr zostanie dodany na końcu formularza. | Dodanie parametru jako pole typu 'Password'. Parametr musi być typu String. Przykład: ... form.addTextPassword('param-1'); ... lub ... form.addPassword({ id: 'param-1', ... }); ... |
hide(elementId) | elementId - identyfikator elementu | Ukrywa pole o podanym id. Przykład ... form.hide('param-1'); ... |
show(elementId) | elementId - identyfikator elementu | Pokazuje pole o podanym id. Przykład: ... form.show('param-1'); ... |
getValue(elementId) | elementId - identyfikator elementu | Pobiera wartość parametru o podanym id. ... form.getValue('param-1'); ... |
setValue(elementId, value) | elementId - identyfikator elementu value - wartość do ustawienia | Ustawia przekazaną wartość do parametru o podanym id. (Obsługuje tylko zmienne nagłówkowe) ... form.setValue('param-1', 'value'); ... |
@ComponentsFormScript( "actions/example-form.js" )
Cache
- Cache jest dostępny dla każdego typu źródła
- Cache może być włączony (i ustawiony czas) dla konkretnej definicji źródła. Decyduje o tym użytkownik w GUI
- Po aktualizacji systemu bez wchodzenia w zakładkę źródeł danych domyślnie wszystkie wtyczki maja cache wyłączony
W builderze wtyczki (DataSourceDefinitionBuilder ) można skonfigurować parametr supportsPagination, który określa czy wtyczka sama obsługuje paginację. Domyślnie jest ustawiony na true.
- jeśli jest włączony cache i paginacja po stronie systemu - pobierane są wszystkie wyniki z DSa nie przekazując paginacji, cachowane są i kolejne wywołania brane są z cache'a (paginując programowo)
- jeśli jest wyłączony cache i paginacja po stronie systemu - za każdym razem pobierane są wszystkie wyniki z DSa i paginacja nakładana jest programowo