Compiler-Sicherheit für Wicket: Bindgen und Wicket-ID-Bindings-Generator

http://wicket.apache.org/

Eine zentrale Schwachstelle von Apache Wicket ist die fehlende Sicherheit zur Übersetzungszeit. Viele Dinge werden als Strings angegeben, so dass simple Tippfehler erst zur Laufzeit und somit schlimmstenfalls erst beim Kunden auffallen. Betroffen sind vor allem drei Bereiche:

  • PropertyModels, in denen Objektattribute als Strings notiert werden:
    new PropertyModel<String>(person, "name");
  • Wicket-ID-Referenzen, die Komponenten mit ihrem Template verbinden:
    <span wicket:id="myLabel"></span> <-> new Label("myLabel")
  • Propertynamen, die vor allem für Übersetzungen benötigt werden:
    new StringResourceModel("page.welcome", this, null);

Bindgen für Wicket

Für das Model-Problem gibt es mit Bindgen Wicket eine verhältnismäßig prominente Lösung. Hier wurde bereits angefragt, ob das Tool nicht offizieller Teil von Wicket 7 werden könnte.

http://wicket.apache.org/
http://wicket.apache.org/

Bindgen ist ein Annotation Processing Tool. Es erzeugt Meta-Klassen, welche die vom Nutzer geschriebenen Klassen und deren Eigenschaften beschreiben. Property-Models können somit compilersicher beschrieben werden:

// ohne Bindgen:
PropertyModel<String>(person, "name");

// mit Bindgen:
BindingModel.of(person, new PersonBinding().name());

// auch über Objektgrenzen hinweg:
BindingModel.of(person, new PersonBinding().address().street());

Kein wackliger String, sondern sichere, generierte Bindingklassen, welche die Attribute der Basisklasse beschreiben.

Annotationprocessing ist mittlerweile fester Bestandteil moderner IDEs, so dass Bindgen nach der einmaligen Einrichtung in etwa Eclipse keiner weiteren Interaktion bedarf. Die Bindings werden stets automatisch aktualisiert.

Wicket-ID-Bindings-Generator für Property-Dateien und HTML-Templates

Von Bindgen inspiriert, hat Ole Langbehn eine analoge Lösung für Property-Dateien und HTML-Templates geschaffen.

// WelcomePage.html
<h1 wicket:id="heading"></h1>

// WelcomePage_de.properties.xml:
<entry key="greetings">Willkommen</entry>

// ohne Wicket-ID-Bindings-Generator
add(new Label("heading", 
    new StringResourceModel("greetings", this, null));

// mit Wicket-ID-Bindings-Generator
add(new Label(WelcomePageWID.heading,
    new StringResourceModel(WelcomePageI18n.greetings, this, null));

Das offizielle Repository auf Github ist momentan nicht mit Wicket > 1.4 kompatibel. Eine Variante für neuere Versionen habe ich in meinem Fork bereitgestellt:

Ole hat angedeutet die Änderungen zu übernehmen, so dass die Updates auch bald im offiziellen Repo zu finden sein sollten.

Die Autovervollständigung nimmt nun noch mehr Arbeit ab und eine potentielle Fehlerquelle ist eliminiert. Bleibt nur noch zu hoffen, dass Wicket diese oder ähnliche Lösungen zukünftig schon von Haus aus mitbringt.