Perfekt passende Funktionen in vier Schritten
Als Softwarehersteller überlegen wir uns bei microTOOL ständig jede Menge nützliche Funktionen für unsere Kunden. Trotzdem kennen wir nicht jeden individuellen Bedarf. Deshalb erreichen uns immer wieder Anfragen, ob wir nicht die eine oder andere Funktion zusätzlich implementieren könnten. Grundsätzlich: Ja. Aber manchmal fallen dafür Wartezeiten und Kosten an.
Sind Sie bereits Anwender unserer Application Lifecycle Management Software objectiF RPM oder des “kleinen Bruders”, der Requirements Engineering Software objectiF RM? Wenn ja, dann wissen Sie wahrscheinlich, dass Sie mit der Muster-Technik zusätzliche Befehle realisieren und wiederholt nutzen können. Doch nicht für alle Wünsche reicht dieses praktische Hilfsmittel aus. Wenn Sie beispielsweise weitere Schnittstellen zu anderen Systemen benötigen, benutzereigene Tool-Funktionen entwickeln wollen oder die Software für das Deployment erweitern möchten, können Sie ab der Version 5.0 von objectiF RPM Erweiterungsfunktionen per Scripting selbst realisieren. Die eigens entwickelten Funktionen lassen sich dann über konfigurierte Kontextmenübefehle, über Zustandsautomaten-Aktionen sowie als Tasks ausführen. Also, legen Sie einfach selbst Hand an.
Was brauchen Sie dazu? Nichts weiter als ein paar Grundkenntnisse in der Programmierung von Java Script und zusätzlich zum objectiF RPM-Server einen Node.js-Server, um die Erweiterungsfunktionen auszuführen. Die Installation und Einrichtung dieses Servers wird aber ganz einfach mit dem Servicemanager durchgeführt – objectiF RPM liefert das alles mit.
In 4 Schritten zur eigenen Funktion
Die folgende Übersicht zeigt Ihnen, welche Vorüberlegungen für die Implementierung einer Erweiterungsfunktion gemacht werden sollten. Wenn Sie die vier W-Fragen geklärt haben, sind Sie in vier schnellen Schritten auch schon am Ziel.
Stellen Sie sich vor, Ihrem Team fehlt eine Funktion zum Verschieben von Anforderungen eines bestimmten Zustands in einen Archiv-Ordner. Ich zeige Ihnen nun anhand dieses Fallbeispiels, wie Sie vorgehen, um diese neue Funktion zu bauen.
Voraussetzungen schaffen
Jetzt trennen Sie nur noch folgende vier Voraussetzungen vom Durchlaufen der vier Schritte:
- Erweiterungsserver
Auf dem Applikationsserver muss mit dem Servicemanager unter Service-Konfiguration ein Node.js-Server eingerichtet werden. Das geht ganz einfach. Sie (oder Ihr Administrator) können ihn automatisch durch Drücken der Schaltfläche Node.js einrichten installieren und aktivieren. Das tun Sie, indem Sie Erweiterungsserver (Node.js) anhaken und dann die Adresse sowie einen Port in das Formular eintragen. Über die Schaltfläche Konfiguration testen prüfen Sie, ob der Erweiterungsserver läuft. Das Ergebnis sollte so aussehen:
- Visual Studio Code
Zum bequemen Editieren und Debuggen der Erweiterungsfunktionen sollte Visual Studio Code auf dem Client-Computer installiert sein.
- Profil und Rechte
Sie arbeiten mit dem Recht Projektadministrator unter dem Nutzungsprofil Administrator und können die Sichten Einstellungen und Stereotypen öffnen.
- Speziell für dieses Beispiel: Zusätzliche Eigenschaft definieren
Für das hier verwendete Beispiel muss außerdem für den Stereotyp Package eine weitere Eigenschaft Archiv (ebenfalls vom Typ Package) definiert sein. Zum Anlegen dieser Eigenschaft öffnen Sie die Sicht Stereotypen und auf Package den Eigenschaftsdialog und wechseln dann auf den Reiter Referenz-Eigenschaftstypen. Das Ergebnis sollte so aussehen:
Schritt 1: Erweiterungsfunktion anlegen
Alles bereit? Dann legen Sie los: Wählen Sie die Sicht Einstellungen, gehen Sie zu Weitere anlegen und klicken Sie auf Erweiterungsfunktion.
Im folgenden Dialog legen Sie zunächst neben dem Namen der Funktion den Stereotyp des Kontextelements fest. Da die Funktion auf einem Anforderungsordner verfügbar sein soll, wählen Sie hier Package oder einen Substereotyp wie Requirements aus. Die benötigten Request- und Response-Schemata lassen Sie sich ganz einfach von objectiF RPM erstellen, genauso wie das Quellcode-Verzeichnis mit der Einstiegsdatei.
Auf dem Reiter Parameter legen Sie noch einen Parameter zur Festlegung des Zustandes der Anforderungen an, die verschoben werden sollen:
Mit der hier gewählten Definition wird später bei der Ausführung der Funktion der Zustand abgenommen automatisch vorgeschlagen, der dann aber wiederum geändert werden kann. Zu guter Letzt speichern Sie nun mit OK ihre neue Erweiterungsfunktion.
Schritt 2: Schema definieren
Wie Sie jetzt sehen, hat objectiF RPM mit dem Anlegen der Erweiterungsfunktion neben Quellcode-Dateien auch gleich eine Schema-Definition erzeugt:
Diese können Sie nun bearbeiten. Legen Sie per Mausklick fest, welche Daten von objectiF RPM für die Erweiterungsfunktion zur Verfügung gestellt werden bzw. welche Daten geändert werden können. Aus dieser Schema-Definition erzeugt objectiF RPM dann ein JSON-Schema für die spätere Ausführung der Erweiterungsfunktion.
In unserem Beispiel werden Informationen über die in einem Ordner vorhandenen Anforderungen und deren Zustände benötigt. Verändert werden soll die Ordnerzuordnung abgenommener Anforderungen. Deshalb müssen auch diese Daten übertragen werden. Außerdem muss der neue Archivordner bekannt sein.
Öffnen Sie nun mit Bearbeiten auf dem ExtensionSchema den Eigenschaftendialog und klappen Sie den Eigenschaftenbaum unter Package auf. Wählen Sie zunächst – ganz wichtig – die Id-Eigenschaft aus und setzen Sie die Option Ist aktuell Pflicht durch Klicken auf das Ausrufezeichen-Symbol.
Diese Id-Eigenschaft muss im Folgenden genauso für die weiteren referenzierten Elementtypen gesetzt werden. Danach definieren Sie die zugehörigen Anforderungen:
mit dem aktuellen Zustand:
dem Besitzer:
und der Archiv-Referenz:
Fertig! Das war es schon. Speichern Sie nun Ihre Änderungen mit OK.
Übrigens, falls Sie nicht nur, wie in diesem Beispiel, die Ordnerzuordnung ändern möchten, sondern vielleicht auch eine Eigenschaft, wie z.B. den Namen eines Elements, dann müssen Sie das ebenfalls im Extension-Schema festlegen. Klicken Sie dazu zusätzlich auf das Stift-Symbol und aktivieren Sie Ist aktuell editierbar:
Schritt 3: Funktionen codieren
Jetzt bestimmen Sie, wie die Daten verändert werden sollen. Starten Sie dazu auf dem automatisch zur Erweiterungsfunktion erzeugten Verzeichnis mit dem Befehl Verzeichnis in VS Code öffnen Visual Studio Code und wählen dort die Datei index.js aus. Hier können Sie nun die Logik Ihrer Erweiterungsfunktion implementieren. objectiF RPM hat für Sie schon eine Einstiegsfunktion generiert, die Sie um den eigenen Code ergänzen können:
Der Code zu unserem Beispiel könnte so aussehen:
Im Parameter source wird in unserem Beispiel der Anforderungsordner übergeben, params enthält den zusätzlich definierten Parameter Zustand als params.stateName.
Beachten Sie, dass im Code die technischen Namen aus der Schema-Definition verwendet werden müssen, mit der Konvention, dass der erste Buchstabe klein geschrieben wird. Die genauen Bezeichner-Namen können Sie im JSON-Schema finden (Kontextmenü-Befehl JSON-Schema ansehen auf dem Extension-Schema).
In dieser Funktion wird zunächst überprüft, ob dem Anforderungsordner ein Archivordner zugeordnet ist. Wenn ja, wird sich dessen Id in der Variable targetOwnerId gemerkt. Anschließend wird die Liste der Anforderungen (source.requirements) des Anforderungsordners durchgegangen und dabei überprüft, ob der Zustandsname der jeweiligen Anforderung dem übergebenen Zustandsnamen entspricht. Wenn ja, wird die Ordnerzuordnung der Anforderung auf den Archivordner geändert.
Abschließend wird zum Speichern der Änderungen die Funktion Response.updateSourceAndPrintMessage aufgerufen, die auch eine Erfolgs- (oder Fehler)meldung im Ausgabefenster von objectiF RPM ausgibt.
Schritt 4: Kontextmenübefehl definieren
Jetzt müssen Sie nur noch definieren, an welcher Stelle die neue Funktion verwendet werden soll. Sie kann als Task, Aktion oder Menübefehl ausgeführt werden.
In unserem Beispiel legen Sie einen Menüpunkt im Kontextmenü fest. Gehen Sie dazu ins Backstage-Menü des Projekts in objectiF RPM und klicken Sie auf Kommandos für Erweiterungsfunktionen.
In der sich öffnenden Liste erzeugen Sie mit + einen neuen Eintrag und nehmen im Dialog Ihre Einstellungen vor:
Geben Sie den Stereotyp an, auf dem das Kommando bzw. der Befehl verfügbar sein soll (Package oder ein Sub-Stereotyp von Package) und wählen Sie die Menügruppe aus, unter der das Kommando erscheinen soll. Weitere Angaben wie Icon oder Lokalisierung sind optional. Und dann können Sie auch schon ausprobieren, ob es funktioniert.
Test
Legen Sie nun in der Produkte-Sicht einen neuen Archiv-Ordner an, wählen Sie den Anforderungsordner (hier User Stories) aus und ordnen Sie diesem unter weitere Eigenschaften den neuen Archiv-Ordner zu. Nun können Sie auf dem Anforderungsordner Ihren neuen Befehl ausführen. Im Optionen-Dialog können Sie den Namen des Zustands der zu verschiebenden Anforderungen noch ändern, bevor Sie die Funktion mit OK starten:
Hat alles geklappt? Dann sollte im Status-Fenster eine entsprechende Erfolgsmeldung erscheinen. Super!
Ups! Es erscheint eine Fehlermeldung! Was tun? Wenn das Problem durch fehlerhaften Code verursacht wird, können Sie debuggen. Halten Sie dazu beim Ausführen des Befehls die Umschalt oder Steuerungstaste gedrückt:
Dann können Sie weitere Einstellungen vornehmen:
Richten Sie gegebenfalls den Erweiterungsserver lokal (auf Ihrem Client-Rechner) ein und folgen Sie der Schritt für Schritt-Anleitung. In Visual Studio Code können Sie in der Datei index.js einen Breakpoint (F9) auf die Funktion setzen und dann im Hauptmenü mit View/CommandPalette den Befehl Debug:Attach to Node Process ausführen.
Wählen Sie dann den entsprechenden Prozess zum Debuggen aus:
Nun können Sie die Erweiterungsfunktion mit OK starten und die Ausführung stoppt am Breakpoint.
Mehr davon
Sicherlich fallen Ihnen Funktionen ein, die Sie auf diese Weise realisieren möchten.
Diskutieren Sie mit.