Codegenerator Framework
Einführung
Das OGenerator Framework wurde aus der Notwendigkeit für effiziente
domainspezifische Codegenerierung heraus, an einem Punkt entwickelt, an dem
Standardcodegeneratoren nicht mehr genug Flexibilität bieten. Denken Sie zum
Beispiel daran verschiedene Klassen für ein bestimmtes Framework, welches Sie
vielleicht selber betriebsintern entworfen haben zu Entwickeln? In diesem Fall
würde ein herkömmlicher Codegenerator vollkommen ausreichen für so Grundlegende
Elemente wie „Class Bodies“. Er würde es ihnen aber nicht ermöglichen
Funktionalitäten, wie die Beziehungen zwischen Klassen und verschiedene Zustände
von Klassen zu implementieren.
Das OGenerator® Framework wurde schon in
verschiedenen Szenarien erfolgreich eingesetzt. Bevor wir Ihnen einige Beispiele
gegeben wollen wir erst einen kurzen Überblick über die Funktionalitäten und die
Verfahrensweisen hinter dem OGenerator® gegeben.
Den OGenerator® verstehen wir
als Framework, weil er entworfen wurde um die schnelle und einfache Schaffung
von speziellen Codegeneratoren zu ermöglichen. Dabei ist zu unterscheiden
zwischen dem OGenerator-Framework und einem Codegenerator der innerhalb dieses
Frameworks erstellt wurde.
Das darauf folgende Kapitel gibt einen Überblick über
die Funktionalität eines Codegenerators der innerhalb des OGenerator® Framework
erstellt wurde. Das letzte Kapitel stellt die OGenerator® Framework Technologie
vor.
Features
Dieser Abschnitt soll einen Kurzen Überblick über die Besonderheiten des Codegenerators geben. Im Kontrast hierzu soll der Abschnitt "Beispiele" durch anhand von schon realisierten Projekten diese abstrakten Ausführungen noch weiter konkretisieren.
Jeder Codegenerator der innerhalb des OGenerator® Frameworks erstellt wurde, ist eine eigenständige, ausführbare Datei.
Nach seiner Programmierung braucht er das OGenerator® Framework nicht mehr. Dies ermöglicht schnelle Codegenerierung und eine einfache Integration in den gesamten Erstellungsprozess.
Der Input für einen Codegenerator liegt immer als XML-Datei vor. Es muss also kein bestimmtes Schema erfüllt werden, aber wenn erwünscht können Schemata geprüft werden. Alles was benötigt wird ist einfach eine gültige XML-Datei. Diese kann einen speziell für Sie entwickelten XML-Dialekt enthalten, oder auch in irgendeinem anderen standardisierten XML-Format vorliegen.
Der Codegenerator unterstützt auch XML-Einfügungen. Das heißt, Sie können ihr Model in beliebig viele XML-Dateien aufteilen um es übersichtlicher zu gestallten, oder Module zu erstellen.
Es können Tags aus einem besonderen XML-Namensraum benutzt werden (meta:trait). Dies ermöglicht wieder verwendbare XML-Einheiten (Traits), welche man an allen anderen Stellen im XML-Model wieder verwenden kann, so dass man mehrfach verwendete Model-Teile nur einmal definieren muss und gleichzeitig nicht auf "copy & paste" zurückgreifen muss. Es ist zudem auf mehrere verschiedene Weisen möglich, solche Traits zu ersetzen.
Der Output eines Codegenerators kann entsprechend den Bedürfnissen des Softwareentwicklungs-Prozesses in jeder erwünschten Anzahl an text-basierten Dateien und in jedes beliebige Verzeichnis erfolgen. Der Output und sein Inhalt werden definiert sobald der Codegenerator fertig gestellt wird.
Der Output kann darüber hinaus in jeder Sprache erfolgen. Wir haben schon Codegeneratoren entwickelt die unter anderem Output in C++, Managed C++, Visual Basic, aspx, Graphviz generiert haben.
Output Dateien können jede Anzahl an gleich bleibenden Code-Teilstücken enthalten. Diese mit eigenen Namen versehen Teilstücke bleiben während des Prozesses der Codegenerierung erhalten und ihr Inhalt kann direkt bearbeitet werden. Auf diese Weise kann man problemlos gleichzeitig an dem abstrakten XML-Model arbeiten und Code schreiben.
Output-Dateien werden auch nur überschrieben, wenn Veränderungen im Model es erfordern ihren Inhalt zu verändern. Es wirkt sich natürlich vorteilig auf den weiteren Arbeitsprozess aus, wenn immer nur die Dateien umgeschrieben werden, welche es wirklich nötig haben.
Zudem können Output-Dateien geordnet werden. Man kann zum Beispiel eine alphabetische Liste aller Funktionen, die in einer Klasse implementiert sind auflisten.
Während man den Codegenerator Entwirft muss man auswählen welche Teile der Software von dem Model generiert werden sollen und welche direkt programmiert werden sollen, mit Hilfe von unabhängigen Dateien, oder gleich bleibender Code-Teilstücke. Es muss also ein Kompromiss gefunden werden, zwischen der Einfachheit des Models und der Menge an generiertem Code. Man muss also an einen Punkt kommen, an dem die größtmögliche Menge an Code geschrieben werden kann, in einer Metasprache, die einen noch vernünftigen Umfang hat. Es besteht dabei das Risiko eine Metasprache zu entwickeln, welche die Ziel-Programmiersprache einfach nur imitiert. Das würde natürlich die ganze Idee eines Codegenerators sinnlos machen.
Technologie
Um Code zu generieren, muss man ein Generator-Template schreiben. Das ist eine Beschreibung wie das XML-Model in Code verwandelt wird. Die Templates für den OGenerator® wurden in MetaC++ geschrieben. MetaC++ ist eine um zwei syntaktische Erweiterungen aufgestockte Version von C++. Die Hauptvorteile von MetaC++ sind das man die ganze Mächtigkeit von C++ und alle für C++ schon bestehenden Bibliotheken nutzen kann und man zudem keine neue Scripting-Sprache erlernen muss. Hier ist ein kleiner Auszug aus einem Generator für Managed C++:
Das Beispiel benutzt einen Editor mit Syntaxhervorhebung. Zeilen die mit ## anfangen werden interpretiert als C++ Code. Ausdrücke welche umschlossen sind von #* und *# werden als Strings interpretiert. Alles Übrige wird als text interpretiert und in den Output geschrieben. Der ganze interpretierte Code ist in diesem Beispiel blau hinterlegt.
Alle MetaC++ Templates laufen in einer Umgebung in welcher der DOM-Knotenbaum des Input-XML-Models zugänglich ist. In dieser Umgebung kann auch auf die Utilities des OGenerator® Frameworks zugegriffen werden:
• Die "SetOutFile()"-Funktion um das Ziel jedes weiteren folgenden Outputs festzusetzen
• Die "PersistentCode()"-Function markiert ein gleich bleibendes Code-Teilstück in generierten Dateien
• Die "PersistentCodeWithStdFill()?"-Funktion kennzeichnet ein gleich bleibendes Code-Teilstück und initialisiert es mit Standart Input
• Der FOREACHOF … ENDFOR Makro dient der Iteration über DOM-Knoten (Support für XPath)
• Die "SelectFirst()"- und "SelectNodes()"-Funktionen prüfen das Vorhandensein von Knoten und greifen auf diese zu.
• Die "GetAttribute()"- und "GetText()"-Funktionen fragen Attribute und den Text von DOM-Knoten ab.
• Die Funktion "OutputList class" gibt eine Liste von Elementen rechts eines Trennsymbols aus.
• Und viele weitere …
Wenn erst einmal ein "MetaC++"-Template geschrieben wurde, wird es von dem OGenerator® Framework zusammen mit den anderen beschriebenen Komponenten (DOM und Utilities Framework) in C++ kompiliert und in einen ausführbaren Codegenerator verwandelt. Dieser Generator verwendet das XML-Model als Input und erstellt selbstständig den – in dem MetaC++ Template definierten – Output.
Codegenerator Outsourcing
Das OGenerator Framework ist einfach zu bedienen und bringt schnelle Ergebnisse. Trotzdem können wir auch auf Sie und ihre Bedürfnisse maßgeschneiderte Generatoren entwickeln. Diesen höchst innovative Service den wir Ihnen bieten, nennen wir Codegenerator Outsourcing. Sie erklären uns ihre Anforderungen und Bedürfnisse und wir erledigen die Entwicklung eines Codegenerators. Sie müssen sich nicht in neue Probleme einarbeiten, sondern können gleich mit unseren Resultaten produktiv arbeiten.
Wir können Codegeneratoren sehr schnell entwickeln und werden uns mit Ihnen gründlich besprechen um die beste domainspezifische Software und das beste Framework mit der Hilfe von Codegeneratoren zu erstellen.