1 Kurzbeschreibung
Eine URL (Uniform Ressource Locator) ist eine universelle Art, Objekte und Dokumente zu adressieren. In früheren Releases von Semiramis wurden in Semiramis auf verschiedene Arten URLs erzeugt oder interpretiert. Für ein einheitliches Verhalten in Semiramis wurde eine Basis für das Handhaben von URLs entwickelt. Dazu gehören die in diesem Dokument beschriebenen kanal-unabhängigen Verknüpfungen. Sie ermöglichen insbesondere die Erstellung von Semiramis-konformen URLs unabhängig davon, ob gerade eine interaktive Semiramis-Anmeldung aktiv ist oder nicht. Dadurch können Hintergrunddienste, wie die Entwicklungsaufträge oder der Workflow, beispielsweise E-Mails versenden, in denen Verknüpfungen auf Anwendungen oder Business Entitys enthalten sind. Eine darüber hinausgehende Erweiterung für den Dialogfall ermöglicht, mit Verknüpfungen Drag & Drop und ähnliche Operationen erwartungskonform und sicher zu implementieren.
2 Zielgruppe
Die Zielgruppe sind hauptsächlich Programmierer, aber auch für Berater enthält das Dokument interessante Informationen.
3 Begriffsbestimmung
Basis-URL
Die Basis-URL ist die Identifikation des in einem Semiramis Application Servers (SAS) integrierten Web-Servers. Unter dieser Identifikation ist eine Anmeldung an den Web-Server möglich. Sie hat die Form einer URL und setzt sich aus Protokoll, Servernamen und Port zusammen. Sie wird für jeden SAS im Systemcockpit definiert.
4 Beschreibung
4.1 Kanal-unabhängige Verknüpfungen
Alle Klassen, die gemeinsam kanal-unabhängige Verknüpfungen realisieren, liegen im Namensraum com.cisag.pgm.util. Unterschieden wird zwischen der Verknüpfung (Link) und der Hilfsklasse (LinkUtility). Der Link ist eine zustandsbehaftete Container-Klasse, das LinkUtitlity ist eine zustandslose Logikklasse.
4.1.1 Klasse Link
Die abstrakte Klasse „Link“ ist die Basisklasse für alle drei Arten von Verknüpfungen, die Semiramis unterstützt. Instanzen von Link können nur durch die Klasse LinkUtility erzeugt werden. Die Klasse Link trägt alle Informationen die notwendig sind, um eine Anmeldung an einem Semiramis Application Server durchzuführen.
- Die Basis-URL des SAS (“https://server:port”).
- Die OLTP-Datenbank, an welcher die Anmeldung erfolgen soll (optional).
- Den Organisationskontext, der nach der Anmeldung gesetzt werden soll (optional).
- Die menschenlesbare Beschreibung (optional).
- Ein Schalter, ob der Link im HTA-Modus gestartet werden soll oder nicht (optional, nur für Application- und BusinessEntityLinks).
Die Basis-URL kann durch das Setzen der GUID des SAS oder durch ausdrückliche Angabe eines String-Wertes festgelegt werden. Um die Datenbank-Auswahl bei der Anmeldung zu überspringen, kann die OLTP-Datenbank gesetzt werden. Die dritte Information, die ein Link aufnehmen kann, ist eine menschenlesbare Beschreibung.
Diese Daten können beim Erzeugen automatisch gefüllt werden. Dazu müssen dem LinkUtility die entsprechenden Flags übergeben werden.
Klasse ApplicationLink
Ein ApplicationLink beschreibt eine Verknüpfung auf eine Anwendung in Semiramis. Er enthält immer die Identifikation der Anwendung. Zusätzlich können eine Aktion und Startparameter angegeben werden.
Klasse BusinessEntityLink
Ein BusinessEntityLink beschreibt eine Verknüpfung auf ein Business Entity in Semiramis. Er enthält immer die Identifikation der Datenbank, in der das Objekt gespeichert ist, und den Primär-Schlüssel des Objektes. Zusätzlich kann der Typ des Objekts abgefragt werden. Außerdem kann optional ein Dependent an den BusinessEntityLink gehängt werden. Damit wird erreicht, dass beispielsweise zu einem Auftrag eine bestimmte Position in den BusinessEntityLink aufgenommen werden kann. Auch vom Dependent kann der Typ abgefragt werden.
Klasse HyperLink
Der HyperLink wird verwendet, um Links zu beschreiben, die keine besondere Bedeutung in Semiramis haben. Er enthält eine frei definierbare URL als einziges Attribut.
4.1.2 Klasse LinkUtility
Diese Hilfsklasse bietet Methoden, um:
- einen neuen Link zu erzeugen,
- einen Link in eine URL umzuwandeln,
- aus einer URL durch Parsen einen Link zu erstellen,
- das Business Entity oder den Dependent eines BusinessEntityLinks zu laden.
4.2 Verknüpfungen für den Dialog-Kanal
Die Klassen, die Verknüpfungen für den Dialogfall verwendbar machen, liegen im Namensraum com.cisag.pgm.gui. Sie verwenden Verknüpfungen für die Implementierung von Drag & Drop, Kopieren, Ausschneiden und Einfügen unterschiedlicher Objekte. Die Funktionen Kopieren, Ausschneiden und Einfügen können sowohl durch die Tastatur als auch durch ein Kontextmenüeintrag ausgelöst werden.
4.2.1 Klasse LinkTransferable
Instanzen der Klasse LinkTransferable repräsentieren eine durch die UI-Klassen von Semiramis transportierbare Hülle um einen Link. Sie enthalten den Link, zusätzliche Daten (additionalData) und eine Unterstützung, um ein erfolgreiches Einfügen mit einem vorherigen Ausschneiden zu verbinden.
LinkTransferable hat generelle Hilfsfunktionen, um:
- einen LinkTransferable aus einem Link zu erzeugen,
- einen LinkTransferable zur Zwischenablage zu kopieren,
- einen LinkTransferable aus dem Zwischenablagen-Inhalt zu erzeugen,
- einen LinkTransferable aus einem anderen Transferable zu erzeugen.
Implementierungsregeln bei Cut & Paste
Wenn ein Element ausgeschnitten wird, wird ein LinkTransferable erzeugt und in die Zwischenablage kopiert. An diesen LinkTransferable kann man einen pastedListener registrieren. Beim Empfangen der pasted-Action kann entschieden werden, ob ein Ausschneiden zulässig war und man kann erkennen, ob das Einfügen erfolgreich war.
Beim Einfügen muss immer die Methode pasted( Object source ) aufgerufen werden. Dabei wird als Wert für den Parameter source der Empfänger der Paste-Opration übergeben, wenn erfolgreich eingefügt wurde. Beim Misserfolg ist als Wert für source null zu übergeben.
Beim Kopieren in die Zwischenablage wird überprüft, ob in der Zwischenablage schon ein ausgeschnittenes Element liegt. Wenn ja, wird automatisch pasted(null) aufgerufen. Dadurch ist beispielsweise möglich, ein durch das Ausschneiden entsprechend markiertes Element wieder zu entmarkieren.
4.2.2 Klasse LinkDnDAdapter
Der LinkDnDAdapter wird benötigt, wenn eine Drag-&-Drop-Unterstützung implementiert werden soll. Der Adapter kann an jedes sichtbare UI-Element gebunden werden. Für Bäume und ihre Knoten ist eine zusätzliche Unterstützung integriert[1], die für andere Elemente ignoriert werden kann und muss. Um den Adapter zu verwenden, muss man ihn beerben. Der konkreten Implementierung stehen vier Methoden zur Verfügung, die das Drag-&-Drop-Verhalten beeinflussen. Alle Methoden erhalten als Eingangsparameter einen TreeNode, falls ein Knoten eines Baumes gezogen wurde, und die vom Benutzer ausgewählte Aktion. Alle Methoden, außer dragStart erhalten zusätzlich noch den im Drag befindlichen LinkTransferable als Parameter und können durch den Rückgabewert die zugelassene Aktion bestimmen.
dragStart() – Liefert einen LinkTransferable zurück, wenn die gewünschte Aktion erlaubt ist. Wenn Drag nicht erlaubt ist, muss null zurückgeliefert werden.
dragOver() – Ist dafür vorgesehen, die gewünschte Aktion vor dem Drop zu beeinflussen. Zurzeit funktioniert aufgrund von Einschränkungen in com.cisag.pgm.dialog nur das Ablehnen aller Aktionen. Dieses ist in einem Baum aber mit Vorsicht zu verwenden, da es sich nicht auf den einzelnen Knoten, sondern auf den gesamten Baum bezieht.
drop() – Wird aufgerufen, wenn der Benutzer das Element fallengelassen hat. Hier wird beeinflusst, ob der Ausgangspunkt (dragStart) von einer Verschiebe- oder Kopier-Aktion ausgehen kann. Nur innerhalb derselben Gruppe sollte ein Verschieben erfolgen. Was zu einer Gruppe gehört hängt vom Einzelfall ab. Beispiel: Die Favoriten sind eine Gruppe, die EntityFields eine zweite.
dragDropEnd() – Ist die Benachrichtigung des Ausgangspunktes, das erfolgreich fallengelassen wurde. Wenn dabei ein Verschieben erfolgt ist, können die Daten im Ausgangspunkt entfernt werden.
Tastaturbeeinflussung des Drag & Drop
Das Verhalten von Drag & Drop kann durch das Drücken von zusätzlichen Tasten, den so genannten Modifier-Keys, beeinflusst werden. Abhängig von den Aktionen die Quelle und Ziel der Operation unterstützen, kann die tatsächlich auszuführende Aktion vom Benutzer ausgewählt werden:
- Keine Taste: Die Aktion ist Verschieben
- Umschalt: Die Aktion ist Verschieben
- Steuerung (Strg): Die Aktion ist Kopieren
- Umschalt + Steuerung (Umschalt+Strg): Die Aktion ist Verknüpfen
Implementierungsregeln für Drag & Drop
Implementierung der Methode dragStart: Die „additionalData“ des LinkTransferable-Objektes sollte den TreeNode oder das VisualElement enthalten.
Implementierung der Methode drop: Verschieben sollte nur innerhalb derselben Gruppe von Elementen (z. B. innerhalb des gleichen Baumes) erfolgen. Wenn nicht sicher ist, ob das Element aus derselben Gruppe stammt, sollte Kopieren oder Verknüpfen als mögliche Aktion zurückgeliefert werden.
4.3 Verknüpfungen für den ODBC-Kanal
In der ODBC-Schnittstelle stehen ab V1R2M0 Links als virtuelles Attribut zur Verfügung. Es trägt den Namen „link_text“ und ist für alle Business Entitys verfügbar, deren Primärschlüssel aus einer GUID besteht. Um es in einem Bericht zu verwenden, kann ein Feld vom Typ Hyperlink mit dem virtuellen Attribut als Datenquelle definiert werden. Beim Anklicken des dadurch entstandenen Links erfolgt der Start des Internet Explorers, die Anmeldung an den Semiramis Application Server zu dem die ODBC-Datenquelle zeigt und das Öffnen der mit dem Business Entity verknüpften Standardanwendung.
Hinweis:
Der Semiramis Application Server, auf den der Link zeigt, kann in der Anwendung Systemcockpit im Feld „Ziel-Server für Link-Attribute“ des Application-Servers, auf den die ODBC-Datenquelle verweist, gesetzt werden.
4.4 URLs
Bis V1R2M0 wurden URLs entweder durch die Klasse com.cisag.pgm.gui.Hyperlink oder durch manuell erstellte Routinen erzeugt. Um in der Entwicklung nicht alle diese Stellen sofort anpassen zu müssen, werden die bisherigen URLs im Moment noch unterstützt. Wie lange die Unterstützung noch enthalten ist, kann nicht vorausgesagt werden. Offiziell gelten die „Erzeugten URLs“.
4.4.1 Erzeugte URLs
Aus Instanzen von Link können URLs berechnet werden. Parameternamen die mit Kleinbuchstaben beginnen sind für die interne Verwendung reserviert. Dies sind unter anderem:
- oltp
- context
- app, appActionId, View
- be, dependent
- id, key, databaseGuid
Parameternamen, die mit Großbuchstaben beginnen, sind für Anwendungsparameter der Aktionen von Semiramis-Anwendungen reserviert. Diese Parameter werden in der Anwendung Entwicklungsobjekte definiert. Der Parametername „View“ ist für die Ansichtensteuerung reserviert. Parameterwerte die mit 0x beginnen werden als hexadezimale Darstellung von Byte-Arrays interpretiert.
Anmerkung:
Die Parameter werden in einer bestimmten Reihenfolge ausgewertet:
- Die OLTP-Datenbank wird für die Anmeldung verwendet.
- Die Organisationseinheit wird als Kontext gesetzt. Das Starten einer Anwendung kann diesen Wert übersteuern.
- Die Anwendung wird gestartet.
- Die ApplicationAction („appActionId“) wird ausgewertet.
- Der Ansichtenparameter („View“) wird ausgewertet.
- Die restlichen Parameter werden in die Felder gesetzt.
Nachfolgend sind zur Verdeutlichung die verschiedenen Formate der URLs schematisch aufgeführt. Innerhalb von Semiramis sollten URLs ausschließlich durch die Link-Klassen erzeugt werden, da das tatsächliche Format der URLs aus technischen Gründen jederzeit geändert oder erweitert werden kann.
Als Typen von Anwendungsparametern werden bei der interaktiven Angabe einer URL als Text nur
- Action-Parameter vom Typ Logischer Datentyp mit primitivem Typ String,
- Action-Parameter vom Typ Business Object, deren Business Object auf genau einem Datenbanktyp existiert und genau ein String-Attribut als Business Key besitzt
unterstützt.
Anmerkung:
Da URLs keine Typ-Informationen enthalten und einer Längenbeschränkung auf 2047 Zeichen unterliegen, werden komplexe Parametersätze wie die Abfragemuster innerhalb von Semiramis serialisiert und in den URLs zu Abfragemustern nur der Verweis auf das entsprechende Business Object versendet.
Anwendungs-URL
<Protokoll>://<Host>[:<Port>]/semiramis.(app|hta)?app=0x<Anwendungs-GUID>[&appAction=<Aktion der Anwendung laut Entwicklungsobjekt>]
[&oltp=<Datenbankname>][&context=<Identifikation der Organisation>]
[&View=<Short-Wert der Ansicht laut Entwicklungsobjekt>]
[<Anwendungsparameter>]
Alternativ gültig:
<Protokoll>://<Host>[:<Port>]/[semiramis.(app|hta)
?app=<Anwendungsname>[&oltp=<Datenbankname>]
[&context=<Identifikation der Organisation>][<Anwendungsparameter>]
Business-Entity-URL
<Protokoll>://<Host>[:<Port>]/semiramis.(app|hta)?be=0x<Identifikation des Entitys>[&dependent =0x<Identifikation des Dependent>]
[&oltp=<Datenbankname>][&context=<Identifikation der Organisation>]
HyperLink-URL
Die erhaltenen URLs haben die Form nach RFC 1738.
Starten einer Base-GUI-Anwendung
Die URLs, um eine Base-GUI Anwendung zu öffnen, werden zwar nicht erzeugt, sind aber dennoch längerfristig gültig. Sie haben folgendes Format, wobei die Klasse eine Unterklasse von com.cisag.pgm.dialog.AbstractApplication sein muss:
<Protokoll>://<Host>[:<Port>]/<Klassenname>.class
4.4.2 Unterstütze, alte URLs
Anwendungs-URL
<Protokoll>://<Host>[:<Port>]/<Klassenname>.class
5 Voraussetzungen
Die hier aufgeführten Funktionen und Schnittstellen sind ab Semiramis 4 verfügbar.
6 Konventionen
Innerhalb von Semiramis sollten URL ausschließlich durch die Link-Klassen erzeugt werden, da das tatsächliche Format der URLs aus technischen Gründen jederzeit geändert oder erweitert werden kann.
7 Vorgehen
Verwenden Sie die oben angeführten Link-Klassen, um Verknüpfungen, Drag & Drop und Copy & Paste zu implementieren.
8 Anwendungsbeispiel: Verwenden von LinkDnDAdapter
DragAdapter für Listen
// verknüpfen des LinkDnDAdapter mit der Liste
new ListDnDAdapter( <list> );
// Implementierung
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);
}
}
[1] Da in einem Baum die Knoten keine eigenen UI-Elemente sind, aber die Bedienung mit Drag & Drop möglich sein soll.