Tutorial

Wie Sie UML Lab an Ihre Bedürfnisse anpassen

Tutorial

Mehr Abstraktion im Modell durch eigene CodeStyles

UML Lab verwendet dieselben Templates sowohl für die Codegenerierung als auch für das Reverse Engineering. Durch deren Anpassung und Ergänzung kann UML Lab leicht an eigene Anforderungen angepasst werden. Dazu verwendet UML Lab sogenannte CodeStyles: Sie verbinden Templates mit UML Profilen.

Beispielsweise kann man in einem CodeStyle projektspezifische Anforderungen an die Implementierung von Zugriffsmethoden wie Getter und Setter kapseln. Dazu redefiniert man das entsprechende Template, die übrigen Templates verbleiben unverändert. Somit erfordern Anpassungen keine Duplizierung von Templates, sondern können mit geringem Aufwand umgesetzt werden.

Auf diese Weise verbessert ein eigener CodeStyle auch die Abstraktion des Modells beim Reverse Engineering von Code. Indem man Templates definiert, die bestimmte Code Blöcke generieren, werden diese Implementierungsdetails nicht in das Modell übertragen. Dadurch werden implementierungsspezifische Attribute und Methoden in der Modellsicht vermieden. Dieses Tutorial zeigt, wie man eigene CodeStyles in UML Lab anlegen kann.

Voraussetzungen

Das Tutorial setzt voraus, dass Sie mit der grundlegenden Funktionsweise von UML Lab vertraut sind. Wenn dies nicht der Fall ist, empfehlen wir zunächst die UML Lab Tour durchzuspielen. Sie finden die Tour unter Help > Cheat Sheets…. Wählen Sie dort bitte die UML Lab Tour.

Inhalt

  1. Setup
  2. Anlegen eines CodeStyle Projekts
  3. Erzeugen eines Templates anhand vorgegebenem Codes
  4. Anlegen eines weiteren Templates
  5. Zusammenfassung

Setup

In diesem Abschnitt werden ein Beispielprojekt importiert und ungewollte Implementierungsdetails im Modell identifiziert. Der entsprechende Code ist der Startpunkt für den neuen CodeStyle.

Zunächst importieren Sie ein Beispielprojekt. Wählen Sie bitte unter File > New > Example… das Code Style Example. Anschließend klicken Sie auf Finish.

Der Code des Beispielprojekts ähnelt dem Shop Example Projekt, das in der UML Lab Tour durchgespielt wird. Allerdings enthält er hier keine Annotationen des Persistenzframeworks JPA. Stattdessen enthält der Code projektspezifische Konventionen, die vom Java Bean Standard abweichen: in den Settern wird jeweils ein Log-Eintrag gemacht.

  • Lassen Sie zunächst den Code von UML Lab reverse engineeren, indem Sie auf dem Beispielprojekt rechtsklicken und File > New > UML Model and Class Diagram wählen. Klicken Sie auf Finish um den Wizard zu beenden.
  • Stellen Sie sich ein Klassendiagramm mit der Klasse Employee zusammen und holen Sie sich mit Hilfe der Fly-out Buttons dessen assoziierte Klassen ins Diagramm: Sie sehen, dass die Klassen sowohl Setter-Methoden, als auch eine uni-direktionale Assoziation zur Klasse Logger haben.
  • Um im Diagramm ein wenig aufzuräumen, könnten Sie im Diagramm auf Logger rechtsklicken und dort Hide Element wählen. Dies entfernt die Klasse Logger aus dem Diagramm und ersetzt alle Referenzen auf sie durch ein Property log in den referenzierenden Klassen.

Auf diese Weise könnte das Diagramm zwar optisch aufgeräumt werden. Es wäre allerdings besser, die tatsächliche Abstraktion des Modells zu erhöhen. Denn Implementierungsdetails sollten nicht im Modell repräsentiert werden. Mit UML Lab erreichen Sie dies leicht durch Anlegen eines eigenen CodeStyle Projekts, das das Logging Konzept abdeckt und so von der konkreten Implementierung im Modell abstrahiert.

Anlegen eines CodeStyle Projekts

Ein eigenes CodeStyle Projekt wird am Einfachsten mit Hilfe des Wizards angelegt. Dies ist auch der Startpunkt für eigene Anpassungen.

Wählen Sie File > New > Other… und dort UML Lab > Code Style Project. Drücken Sie Next.

Geben Sie als erstes dem Projekt einen Namen. Tragen Sie hier Logger ein. Klicken Sie auf Next um zur nächsten Seite zu gelangen.

Auf der letzten Wizard Seite ist der Name des CodeStyles bereits mit dem Namen des Projekts Logger vorbelegt. Als nächstes müssen wir uns entscheiden, welchen existierenden CodeStyle unser Logger CodeStyle erweitern soll. An dieser Stelle reicht es, den vorgewählten standard CodeStyle zu belassen. Nun können wir die Templates wählen, die wir in unserem neuen CodeStyle überschreiben wollen. Natürlich können Sie später jederzeit weitere Templates hinzufügen. Beginnen wir mit dem Feld log, das alle Java Klassen als Implementierungsdetail haben. Um hiervon zu abstrahieren, gehen wir wie folgt vor:

  • Zielsprache java ist natürlich richtig.
  • Da das Feld log ein Member der Java Klassen ist, kann es sich an beliebiger Position im Rumpf einer Klasse befinden. Wenn Sie den Source Code verschiedener Klassen miteinander vergleichen, werden Sie feststellen, dass dies im Beispielprojekt auch der Fall ist.
  • Das Template File.xpt deckt diese Art von Source Code ab, indem es die Klassen generiert. Klappen Sie den entsprechenden Knoten im Baum aus.
  • Elemente, die ein technisches Implementierungsdetail im Rumpf einer Java Klasse sind und nicht im Modell erscheinen sollen, werden in der UML Lab Template API als additionalMember bezeichnet. Wählen Sie den Eintrag Fragment Single unter Template additionalMember im Baum aus.
  • Klicken Sie auf Finish um den Dialog zu beenden.

Anpassen der Templates

UML Lab verwendet zum Einlesen des Quelltextes Templates. Diese können leicht aus vorgegebenem Source Code abgeleitet werden. Im Beispiel wird das Reverse Engineering von UML Lab die allgegenwärtigen log Felder als Implementierungsdetails identifizieren und nicht im Modell anlegen. Modellseitig wird dies durch die Wahl des Logger CodeStyles repräsentiert.

Der Wizard hat bereits das Template File.xpt aus dem gerade angelegten Logger Projekt geöffnet. Es befindet sich im Unterordner /templates/. Entfernen Sie den vom Standard CodeStyle kopierten Rumpf des Templates zwischen «DEFINE additionalMember» und «ENDDEFINE». Kopieren Sie anschließend folgenden Templatecode und speichern Sie im Anschluss die Datei.

«IF Class.isInstance(parent)»
   private static final Logger log = 
                        Logger.getLogger("«getQualifiedName(".")»");
   «addImport("java.util.logging.Logger")»
«ENDIF»

UML Lab verwendet Eclipse Xpand als Template Sprache. Die Xpand Reference dokumentiert die Sprachkonstrukte. Im Wesentlichen werden im vorliegenden Templatecode folgende Konstrukte verwendet:

  • Das Template soll nur für Klassen verwendet werden. Insbesondere soll das log Feld nicht für Interfaces generiert werden. Das IF Statement innerhalb der Guillemets («…») entspricht einer normalen Kontrollstruktur. In diesem Fall prüft die Bedingung, ob der gegebene Classifier eine UML Class ist (Class.isInstance()).
  • Der Text außerhalb der Guillemets wird direkt in den Source Code generiert. An dieser Stelle wurde die Deklaration des log Felds direkt vom Code in das Template kopiert.
  • Deklarationen des log Felds verwenden den vollqualifizierten Klassennamen als Parameter. Hierzu verwenden wir die vordefinierte Hilfsmethode getQualifiedName("."). Auch dies erfolgt in Xpand innerhalb von Guillemets. Bei der Ausführung des Templates wird hier der berechnete Wert ausgegeben.
  • Damit neu generierter Source Code keine Compilefehler enthält, müssen noch Import Statements hinzugefügt werden. Auch dies wird durch den Aufruf einer Hilfsmethode erreicht.

Das fertige Template sieht wie folgt aus:

Nach Anlegen des eigenen Templates muss UML Lab den Source Code erneut einlesen. Dafür rechtsklicken Sie bitte das UML Model im Package Explorer und wählen UML Lab > Reparse all files.

UML Lab fragt nun in einem Dialog nach, ob die geänderten Templates neu geladen werden sollen. Bestätigen Sie hier mit Yes.

UML Lab berücksichtigt beim erneuten Einlesen der Dateien auch das gerade angelegte Template.

Selektieren Sie eine Klasse im Diagramm und wählen Sie das Codestyle Tab des Properties Views. Klassen, die ein log Feld haben, auf das das neue Template passt, werden in den Properties mit Logger CodeStyle annotiert. Daher ist das log Property bzw. die Referenz zur Klasse Logger im Modell auch nicht mehr präsent. Weiterhin generiert UML Lab aus dem Modell denselben Source Code, der auch eingelesen wurde.

Hinzufügen weiterer Templates

Das Klassendiagramm enthält weitere unerwünschte Implementierungsdetails: die Setter Methoden der verschiedenen Java Felder. Ursache hierfür ist, dass im Source Code der Setter jeweils ein log.log() Statement steht. Der Setter wird daher von UML Lab nicht als solcher erkannt. Deshalb legen wir nun ein weiteres Template an.

Hierfür rechtsklicken Sie bitte das Logger Projekt im Package Explorer und wählen Sie dort Edit > Redefine Templates um den bereits bekannten Wizard anzuzeigen.

Die Setter Methode sollte im Modell einer UML Property zugeordnet werden. Daher wählen Sie das Template Attribute.xpt und klappen Sie dieses sowie die Kindknoten in der Baumansicht aus. Sie sehen, dass für ein UML Property drei unterschiedliche Fragmente verfügbar sind. Fragmente sind ein Konzept in UML Lab. Es handelt sich um Templates, die Source Code für ein gemeinsames UML Element generieren - aber an jeweils unterschiedlichen Positionen im Source Code. Wählen Sie bitte das Fragment für den Setter und klicken Sie auf Finish.

Das neue Template wird automatisch geöffnet. Es befindet sich wieder im /templates/ Verzeichnis des Logger Projekts. Die Zeile mit dem log Statement ist immer die erste Zeile der Setter. Suchen Sie diese Position im Template. Es ist die Zeile nach der öffnenden geschweiften Klammer. Kopieren Sie nun das log Statement entweder aus einer existierenden Java Klasse oder verwenden Sie das folgende Template.

{
   log.log(Level.FINE, "change «name»");
   «addImport("java.util.logging.Level")»
   «"   " + thisName(parent)» = «value»;
}
  • Die erste Zeile ist aus dem Source Code kopiert und wird vom Codegenerator direkt geschrieben.
  • Der geloggte Eintrag enthält den Namen des Feldes. Dazu wird der Ausdruck «name» verwendet.
  • Wie zuvor sollte auch an dieser Stelle die verwendete Bibliotheksklasse zu den Imports hinzugefügt werden.

Das fertige Template sieht wie folgt aus:

Lassen Sie den Source Code schließlich von UML Lab erneut einlesen. Dies wird alle Setter Methoden aus dem Modell entfernen und die entsprechenden Properties mit dem Logger Code Style versehen. Die entsprechenden Implementierungsdetails sind nunmehr in den Templates enthalten und werden daher nicht mehr im Modell benötigt.

Fazit

Das Tutorial hat gezeigt, wie man die mitgelieferten Template-Sätze von UML Lab durch gezieltes Anpassen einzelner Templates erweitern kann. Hiermit können Sie eigene Coding-Konventionen in CodeStyles fassen. UML Lab lernt dadurch, mit neuen Implementierungsstilen umzugehen und beim Reverse Engineering von Implementierungsdetails zu abstrahieren. Natürlich können die so erzeugten CodeStyles auch bei der Modellierung neuer Elemente verwendet werden. Setzt man auf einer neu angelegten Klasse den Logger Style in der CodeStyle Eigenschaftenseite, so enthält der generierte Quelltext die im CodeStyle definierte Logger Deklaration. Attribute der Klasse erben standardmäßig den CodeStyle und enthalten daher ebenfalls automatisch den log.log(…) Code in ihren Settern.

Die Lösung dieses Tutorials ist in UML Lab auch als eigenes Beispielprojekt enthalten. Sie finden es unter File > New > Example… > Logger Code Style - stage 1.