Wprowadzenie
Adres URL (Uniform Resource Locator) to uniwersalny sposób adresowania obiektów i dokumentów. w artykule opisano łącza niezależne od kanału, które w szczególności umożliwiają tworzenie adresów URL zgodnych z systemem niezależnie od tego, czy interaktywny login jest aktualnie aktywny, czy nie. Umożliwia to usługom działającym w tle, takim jak zadania programistyczne lub Workflow, wysyłanie wiadomości e-mail zawierających łącza do aplikacji lub jednostek biznesowych. Dodatkowe rozszerzenie dla okien dialogowych umożliwia realizację opcji: drag&drop oraz podobnych operacji.
Grupa docelowa
- programiści
- konsultanci techniczni
Opis
Linki niezależne od kanału
Wszystkie klasy, które wspólnie implementują połączenia niezależne od kanału, znajdują się w przestrzeni nazw com.cisag.pgm.util. Rozróżnia się powiązanie (LInk) i klasę pomocniczą (LinkUtility). Link jest klasą kontenerową z zachowaniem stanu, natomiast LinkUtility jest bezstanową klasą logiczną.
Klasa Link
Klasa abstrakcyjna Link jest klasą bazową dla wszystkich typów łączy obsługiwanych przez system. Instancje Link mogą być tworzone wyłącznie przez klasę LinkUtility. Klasa Link zawiera wszystkie informacje niezbędne do zalogowania się do serwera aplikacji systemu.
- Podstawowy adres URL SAS-a („https://server:port”).
- Baza danych OLTP do której powinno nastąpić logowanie (opcjonalnie).
- Kontekst organizacji, który ma zostać ustawiony po zalogowaniu (opcjonalnie).
- Czytelny opis (opcjonalnie).
- Ustawienie określające, czy link ma zostać uruchomiony w trybie HTA, czy nie (opcjonalnie, tylko dla Application- i BusinessEntityLinks).
Podstawowy adres URL można ustawić, ustawiając identyfikator GUID SAS-a lub jawnie określając wartość ciągu. Aby pominąć wybór bazy danych podczas logowania można ustawić bazę OLTP. Kolejną informacją, jaką może zawierać link, jest czytelny opis.
Dane te mogą zostać uzupełnione automatycznie podczas ich tworzenia. W tym celu należy przekazać odpowiednie flagi do narzędzia LinkUtility.
Klasa ApplicationLink
ApplicationLink opisuje powiązanie z aplikacją w systemie. Zawsze zawiera identyfikator aplikacji. Dodatkowo można określić parametry akcji i startu.
Klasa BusinessEntityLink
BusinessEntityLink opisuje łącze do jednostki biznesowej w systemie. Zawsze zawiera oznaczenie bazy danych, w której przechowywany jest obiekt oraz klucz główny obiektu. Dodatkowo można sprawdzić typ obiektu. Opcjonalnie do BusinessEntityLink można dołączyć element zależny (Dependent), co pozwala na przykład na dołączenie konkretnej pozycji do zamówienia w BusinessEntityLink. Również w przypadku elementu zależnego można zapytać o jego typ.
Klasa HyperLink
HyperLink służy do opisywania linków, które nie mają zastosowania w systemie. Zawiera dowolnie definiowany adres URL jako jedyny atrybut.
Narzędzie klasy Link
Ta klasa pomocnicza udostępnia metody umożliwiające:
- utworzenie nowego łącza
- konwertowanie linku na adres URL
- utworzenie linku z adresu URL poprzez jego analizę
- załadowanie jednostki biznesowej lub element zależny (dependent) od BusinessEntityLink.
Powiązania dla kanału dialogowego
Klasy umożliwiające wykorzystanie powiązań w przypadku okna dialogowego, znajdują się w przestrzeni nazw com.cisag.pgm.gui. Wykorzystują one powiązania do implementacji operacji takich jak Drag & Drop, kopiowanie, wycinanie oraz wklejanie różnych obiektów. Funkcje kopiowania, wycinania i wklejania można wywołać zarówno za pomocą klawiatury, jak i poprzez menu kontekstowe.
Klasa LinkTransferable
Instancje klasy LinkTransferable reprezentują przenośną przez klasy interfejsu użytkownika (UI) otoczkę wokół linku. Zawierają link, dodatkowe dane oraz wsparcie umożliwiające połączenie pomyślnego wklejenia z wcześniejszym wycięciem.
LinkTransferable posiada ogólne funkcje pomocnicze, umożliwiające:
- utworzenie LinkTransferable z linku
- skopiowanie LinkTransferable do schowka
- utworzenie LinkTransferable z zawartości schowka
- utworzenie LinkTransferable z innego Transferable
Zasady implementacji operacji Wytnij i Wklej (Cut & Paste)
Gdy element zostanie wycięty, tworzony jest obiekt LinkTransferable i kopiowany do schowka. Do tego obiektu można zarejestrować pastedListener. Podczas odbierania akcji pasted można zdecydować, czy wycięcie było dopuszczalne oraz sprawdzić, czy wklejenie zakończyło się powodzeniem.
Podczas wklejania zawsze należy wywołać metodę pasted(Object source). Jeśli wklejanie się powiodło, parametrem source powinien być odbiorca operacji wklejania. W przypadku niepowodzenia jako wartość source należy przekazać null.
Podczas kopiowania do schowka sprawdzane jest, czy w schowku znajduje się już wycięty element. Jeśli tak, automatycznie wywoływana jest metoda pasted(null). Dzięki temu można m.in. automatycznie usunąć oznaczenie elementu, który został wcześniej oznaczony jako wycięty.
Klasa LinkDnDAdapter
LinkDnDAdapter jest potrzebny, gdy ma zostać zaimplementowane wsparcie dla funkcji Drag & Drop. Adapter może być powiązany z dowolnym widocznym elementem interfejsu użytkownika. Wbudowana jest dodatkowa obsługa drzew i ich węzłów, którą należy zignorować w przypadku innych elementów. Aby użyć adaptera, należy go odziedziczyć.
Do konkretnej implementacji dostępne są cztery metody, które wpływają na zachowanie funkcji Drag & Drop. Wszystkie metody otrzymują jako parametr wejściowy obiekt typu TreeNode, jeśli został przeciągnięty węzeł drzewa, oraz akcję wybraną przez użytkownika. Wszystkie metody, poza dragStart, otrzymują dodatkowo jako parametr obiekt LinkTransferable znajdujący się w trakcie przeciągania i mogą określić dozwoloną akcję za pomocą wartości zwracanej.
- dragStart() – zwraca LinkTransferable, jeśli żądana akcja jest dozwolona. Jeśli przeciąganie nie jest dozwolone, należy zwrócić wartość null.
- dragOver() – służy do wpływania na żądaną akcję przed upuszczeniem. Ze względu na ograniczenia w com.cisag.pgm.dialog obecnie działa jedynie odrzucenie wszystkich akcji. W przypadku drzewa należy zachować ostrożność, ponieważ wpływa to na cały obiekt drzewa, a nie tylko na pojedynczy węzeł.
- drop() – opcja jest wywoływana, gdy użytkownik upuścił element. W tym miejscu określa się, czy punkt początkowy (dragStart) może wynikać z akcji przeniesienia czy kopiowania. Przenoszenie powinno odbywać się wyłącznie w obrębie tej samej grupy. To, co należy do grupy, zależy od indywidualnego przypadku.
- dragDropEnd() – powiadomienie punktu początkowego o pomyślnym upuszczeniu. Jeśli doszło do przeniesienia, dane w punkcie początkowym mogą zostać usunięte.
Wpływ klawiatury na funkcję Drag & Drop
Zachowanie funkcji Drag & Drop może być modyfikowane przez naciśnięcie dodatkowych klawiszy, tzw. klawiszy modyfikujących. W zależności od działań wspierających źródło i cel operacji, użytkownik może wybrać rzeczywistą akcję do wykonania:
- brak przycisku – akcja to przeniesienie
- Shift – akcja to przeniesienie
- Ctrl – akcja to kopiowanie
- Shift + Ctrl – akcja to utworzenie powiązania
Zasady implementacji Drag & Drop
Implementacja metody dragStart: additionalData obiektu LinkTransferable powinna zawierać TreeNode lub VisualElement.
Implementacja metody drop: przenoszenie powinno odbywać się wyłącznie w obrębie tej samej grupy elementów (np. w obrębie tego samego drzewa). Jeżeli nie jest się pewnym czy element pochodzi z tej samej grupy, jako możliwą akcję należy zwrócić kopiowanie lub tworzenie powiązania.
Powiązania dla kanału ODBC
W interfejsie ODBC linki są dostępne jako wirtualne atrybuty o nazwie link_text i jest dostępny dla wszystkich jednostek biznesowych, których klucz główny składa się z identyfikatora GUID . Aby użyć go w raporcie, można zdefiniować pole typu Hyperlink z atrybutem wirtualnym jako źródłem danych. Po kliknięciu powstałego łącza zostanie uruchomiona przeglądarka, i nastapi zalogowanie się do serwera aplikacji systemu, na który wskazuje źródło danych ODBC i otworzy się standardowa aplikacja powiązana z jednostką biznesową.
Serwer aplikacji systemu, na który wskazuje link, można ustawić w aplikacji Panel System po wybraniu typu Serwer aplikacji w polu Docelowy serwer dla atrybutów linku, na który wskazuje źródło danych ODBC.
Adres URL
Wygenerowane adresy URL
- oltp
- context
- app, appActionId, View
- be, dependent
- id, key, databaseGuid
Nazwy parametrów rozpoczynające się od wielkich liter są zarezerwowane dla parametrów aplikacji akcji w aplikacjach systemu. Te parametry są definiowane w aplikacji Obiekty deweloperskie. Nazwa parametru View jest zarezerwowana do sterowania widokiem. Wartości parametrów rozpoczynające się od 0x są interpretowane jako szesnastkowa reprezentacja tablic bajtów.
Dla przejrzystości różne formaty adresów URL zostały przedstawione schematycznie poniżej. W systemie adresy URL powinny być generowane wyłącznie przez klasy Link, ponieważ rzeczywisty format adresów URL można w każdej chwili zmienić lub rozszerzyć z przyczyn technicznych.
Typy parametrów aplikacji używane podczas interaktywnego określania adresu URL jako tekst:
- parametry akcji typu Logiczny typ danych z pierwotnym typem String
- parametry akcji typu Obiekt biznesowy, których obiekt biznesowy istnieje dokładnie w jednym typie bazy danych i posiada dokładnie jeden atrybut typu String jako klucz biznesowy
Adres URL aplikacji
<Protokół>://<Host>[:<Port>]/semiramis.(app|hta)?app=0x<identyfikator GUID aplikacji>[&appAction=<Działanie aplikacji zgodnie z obiektem deweloperskim>] [
&oltp=<Baza danych nazwa>] [&context=<Identyfikator organizacji>]
[&View=<Krótka wartość widoku według obiektu opracowania>]
[<Parametry aplikacji>]
Alternatywnie poprawne:
<protokół>://<host>[:<port>]/[semiramis.(app|hta)
?app=<nazwa aplikacji>[&oltp=<nazwa bazy danych>]
[&context=<identyfikacja organizacji>][<aplikacja parametry>]
Adres URL jednostki biznesowej
<Protokół>://<Host>[:<Port>]/semiramis.(app|hta)?be=0x<Identyfikator podmiotu>[&dependent=0x<Identyfikator podmiotu Dependent>]
[&oltp=<Nazwa bazy danych >][ &context=<Identyfikator organizacji>]
Adres URL hiperłącza
Uzyskane adresy URL mają postać zgodną z RFC 3986.
Instrukcja: Wykorzystanie LinkDnDAdapter
DragAdapter dla list
// połącz LinkDnDAdapter z listą
nowy ListDnDAdapter( <list>);
// Implementacja
private class ListDnDAdapter extends LinkDnDAdapter { List list; public ListDnDAdapter (List list) { super(list); this.list = list; setDropGesture(LinkDnDAdapter.NONE); } protected int dragOver(TreeNode node, LinkTransferable linkTransferable, int action) { return LinkDnDAdapter.NONE; } protected int drop(TreeNode node, LinkTransferable linkTransferable, int action) { return LinkDnDAdapter.NONE; } protected void dragDropEnd(LinkTransferable linkTransferable, int action) { // Do Nothing } protected LinkTransferable dragStart( TreeNode node, int action ) { CisListPartMutable rowMutable = list.getSelectedRow(); if (rowMutable == null) { return null; } CisObject rowData = ( CisObject )rowMutable.getData(); Link link = LinkUtility.createBusinessEntityLink( LinkUtility.DEFAULT_FLAGS , <databaseGuid>, rowData); return LinkTransferable.fromLink(link); } }