Codegenerierung mit Eclipse Xtend

Modularisierung

Nehmen wir an, wir wollen die im vorherigen Abschnitt definierte Sortierfunktion in einem anderen Kontext wiederverwenden. Dafür wollen wir sie in eine eigene Datei verschieben. In Java würden wir sie wahrscheinlich als statische Methode in eine Hilfsklasse auslagern. Dadurch würden allerdings sämtliche Aufrufe auch statisch auf diese Klasse gelinkt. Eine andere Implementierung dieser Methode ist dann nicht mehr realisierbar, ohne die verwendenden Klassen zu verändern und neu zu kompilieren. Um dieses Problem zu beheben, verwenden wir Dependency Injection (DI) [4]. Zunächst erzeugen wir eine neue Xtend-Klasse, welche die sortBy-Funktion deklariert:

  class ClassExtensions {
    def sortedFields(Class> clazz) {
      clazz.declaredFields.sortBy(f | f.name)
    }
  }

Um diese Funktion nun zu verwenden, muss ein Feld mit der Annotation @Inject deklariert werden :

  class SimpleJavaBeansGenerator {
    @Inject extension ClassExtensions classExtensions
    .
  }

Durch das Schlüsselwort extension stehen alle Methoden am Feld auch als Extension Method zur Verfügung. Würde man das Schlüsselwort weglassen, müsste man also zwingend classExtensions.sortedFields(clazz) schreiben und könnte nicht das leserlichere clazz.sortedFields verwenden. Die Annotation @Inject erklärt dem verwendeten DI-Container, dass hier eine Abhängigkeit besteht und ein entsprechendes Objekt gesetzt werden muss. Um das Beispiel auszuführen, müssen die Xtend-Klassen nun mit einem DI-Container erzeugt werden. Wir verwenden in unserem Beispiel Google Guice [5]:

  public static void main(String[] args) {
    Injector injector = Guice.createInjector();
    SimpleJavaBeansGenerator instance = 
      injector.getInstance(SimpleJavaBeansGenerator.class);
    System.out.println(instance.generateJavaCode(String.class));
  }

Für den Standardfall reicht es aus, einen unkonfigurierten Injector zu erzeugen und diesem dann die Instanziierung der Xtend-Klassen zu überlassen.

Stellen Sie sich nun vor, dass Sie den selben Generator in unterschiedlichen Szenarien verwenden wollen und in einer der Situationen unglücklich mit der Sortierstrategie sind. Kein Problem: Sie müssen lediglich eine neue Xtend-Unterklasse definieren und die entsprechende Funktionalität überschreiben. Wenn Sie die Sortierung umdrehen möchten, könnte die neue Implementierung z. B. so aussehen:

 class SpecialClassExtensions extends ClassExtensions {
    override sortedFields(Class> clazz) {
      super.sortedFields(clazz).reverse
    }
 }

Damit Guice nun die „gepatchte“ Version verwendet, muss lediglich der Injector angepasst werden, und schon werden alle Abhängigkeiten auf ClassExtensions mit einer Instanz von SpecialClassExtensions erfüllt :

public static void main(String[] args) {
  Injector injector = Guice.createInjector(new AbstractModule(){
    @Override
    protected void configure() {
      bind(ClassExtensions.class).to(SpecialClassExtensions.class);
    }
   });
   ...
Fazit

Xtend ist eine moderne Programmiersprache, die sich dank ihrer Template-Expression und einem cleveren Editor hervorragend für Codegenerierung eignet. Sie hat eine für Java-Programmierer leicht zu erlernende, prägnante Syntax und reichhaltige Expressions mit Closures und Typ-Inferenz. Da Xtend Java-Typen benutzt und zu Java-Code kompiliert wird, integriert sich Xtend-Code nahtlos in Java-basierte Anwendungen. In diesem Artikel konnten wir leider wirklich nur an der Oberfläche dessen kratzen, was Xtend kann. Weitere nützliche Sprachfeatures, wie beispielsweise das dynamische Dispatching von überladenen Methoden, werden im Tutorial-Projekt veranschaulicht und in der Sprachreferenz ausführlich beschrieben (Kasten: 3, 2, 1 , los! ).

.
Das nächste Release von Xtend ist für Dezember 2011 geplant und wird neben einigen neuen Features in der Sprache und der IDE eine Maven-Integration mitbringen. Dann können Sie die Xtend-Kompilierung in einem Maven Build integrieren und die Laufzeit-Bibliothek aus einem Maven Repository beziehen.

3, 2, 1, los!

Um mit Xtend loszulegen, müssen Sie nur die Classic-Variante von Eclipse 3.7 (Codename Indigo) passend für Ihr System herunterladen, entpacken und starten. Sie können nun über den Marketplace-Client in Eclipse HELP -> ECLIPSE MARKETPLACE . das Xtend SDK beziehen.

Zunächst sollten Sie einen Blick in das Tutorial-Projekt werfen. Dazu wählen Sie FILE > NEW.. > PROJECT . und dann im Dialog „Xtend Tutorial“ aus. Das erstellte Projekt enthält eine Reihe verschiedener Xtend-Klassen, die entsprechend ihrem Namen jeweils einen Aspekt der Sprache beleuchten. Schauen Sie sich die Dateien an und führen Sie ruhig Änderungen durch. Im Ordner xtend-gen befindet sich der nach Java übersetzte Quelltext. Falls Sie mehr über das eine oder andere Sprachfeature nachlesen möchten, finden Sie eine Sprachreferenz in der Eclipse-Hilfe. Viel Spaß!

Sven Efftinge leitet für die itemis AG den Standort Kiel. Er ist Projektleiter von Xtend (http://xtend-lang.org) und Xtext (www.xtext.org) Xtext (www.xtext.org) und spricht regelmässig auf Konferenzen, schreibt für Fachmagazine und ist Koautor eines Buchs zum Thema Modellgetriebene Softwareentwicklung.

Dr. Jan Köhnlein arbeitet als Softwarearchitekt und Berater bei der itemis AG in Kiel. Seine Spezialisierung liegt in der Entwicklung Eclipse-basierter Werkzeuge für domänenspezifische Sprachen und modellgetriebene Softwareentwicklung. Er ist einer der Kern-Committer für das Eclipse-Projekt Xtext.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.