Java Getriebe

Java und NetBeans

Leben im Dateisystem – die layer.xml von NetBeans

Ich bin nicht der erste und vermutlich werde ich nicht der Letzte sein, der sich über die „layer.xml“ von NetBeans auslässt. Dieses Rückgrat der NetBeans Plattform ist aber viel zu interessant um es links liegen zu lassen.

Der erste Entwurf dieses Artikels datiert auf April und September 2010 zurück. Seinerzeit war noch NetBeans 6.9 aktuell. Seit dem haben sich einige Dinge bezüglich Layer getan. Vor allem werden kaum noch Einträge direkt in der Layer getätigt, sondern von Annotations(-Prozessoren) dort eingetragen. Die Grundfunktion der Layer als globale Konfigurationsdatenbank ist aber weiterhin aktuell, weswegen auch dieser Artikel in großen Teilen noch so tut als gäbe es keine Annotations.

Was ist die layer.xml

Sobald man sich entscheidet ein Modul für die NetBeans IDE oder gar eine eigene Suite auf Basis der NetBeans Plattform zu schreiben, dauert es nur wenige Klicks, bis man auf den Eintrag „create layer.xml“ stößt. Kurze Zeit später, nach dem Gebrauch der ersten Wizards, füllt sich diese ominöse XML Datei mit allerlei Inhalt. Und die wenigsten Neulingen in der NetBeans RCP Programmierung weiß, was das alles soll oder warum das wirklich so ist. Und um das vorweg zu nehmen: Auch die wenigsten erfahrenen NetBeans RCP Programmierer kennen alle Aspekte dieser Datenstruktur.

Denn genau das ist die „layer.xml“ eigentlich. Eine große Datenstruktur. Genau gesagt ein simpler Baum. Die „korrekte“ Bezeichnung innerhalb von NetBeans ist „System Filesystem“ aber meiner Meinung nach ist dieser Begriff bei Beginnern eher irreführend. Das Glossar schreibt von

The general registry that contains NetBeans configuration information […]

und somit ist dieses „System FileSystem“ recht gut mit der Registry von Windows vergleichbar. Es sind unheimlich viele „Knoten“ im Baum und dazu sind viele „Blätter“ mit den eigentlichen Daten. Die Knoten werden in NetBeans „Folder“ genannt und die Blätter des Baums heißen „File“. Auch diese Benennung irritiert in meinen Augen zunächst mehr als dass es hilft. Die Assoziation mit dem Dateisystem auf der eigenen Festplatte ist einfach zu schnell hergestellt, aber trifft die Sache nur unzureichend.

Betrachtet man dieses „Dateisystem“ einfach als simple Baum-Datenstruktur werden ein paar Dinge vielleicht einfacher 1.

Was bringt mir die layer.xml

Wie schon gesagt, die Layer Datenstruktur beinhaltet nahezu alle Konfigurationseinstellungen der NetBeans RCP Anwendung. Angefangen von den sichtbaren Menüzeilen und Symbolleisten oder die Anordnung der einzelnen Fenster des Hauptfensters über Angaben zu den bekannten Dateitypen bis hin zu quasi allem was im Optionsdialog eingestellt werden kann. Eine Liste der von NetBeans selbst definierten Einträge gibt es in den JavaDocs der Plattform.

Dies bedeutet, dass egal was ich an einer NetBeans RCP 2 verändern möchte, an der Layer Datenstruktur komme ich nicht vorbei. Um so wichtiger ist es, dass man das Prinzip hinter dieser Struktur verstanden hat. Auch wenn es mittlerweile viele „Wizards“ in der IDE gibt, die einen unheimlich viele Dinge abnehmen sollte man zumindest „lesen“ können, was der Assistent da generiert hat. Dazu ist es unabdingbar sich den folgenden Satz zu verinnerlichen:

Interpretation ist alles

Wie auch im „tatsächlichen“ Dateisystem auf der Festplatte werden auch erst durch die Interpretation des Betriebssystem bestimmte Ordner besondere Ordner. So ist C:\Windows\System32 zunächst Mal ein einfacher Ordner. Erst das Betriebssystem sagt In diesem Ordner sollen alle Systembibliotheken abgelegt werden oder der Ordner /etc ist erst durch die Interpretation des Betriebssystems zu der Stelle an der Konfigurationsdateien abgelegt werden sollen.

Genau so verhält es sich auch in der Layer Datenstruktur. Die XML Datenstruktur besteht eigentlich nur aus ineinander geschachtelten <folder> Einträgen mit den <file> Einträgen als „Blätter“. Dazu kommen noch ein paar <attr> Einträgen, mit denen man die beiden anderen Eintragstypen ergänzen kann. Das war es. Erst die Tatsache, dass die NetBeans RCP definiert in <folder name="Menu"> suche ich die Einträge für die Menüzeile macht aus diesem Eintrag etwas „Besonderes“.

Wie mache ich meine eigenen Einträge

Dieser Umstand, dass das „Betriebssystem“ 3 nur an bestimmten Stellen sucht und die Einträge nach seinem Gutdünken interpretiert, ist es zu verdanken, dass man (wie auch im realen Dateisystem) beliebige eigene Einträge erstellen kann. Man muss lediglich wissen wie interpretiert die RCP diesen Eintrag oder aber selber für die Interpretation sorgen.

NetBeans bietet dazu mit der Methode FileUtil.getConfigFile() einen sehr einfachen Mechanismus um an das entsprechende FileObject zu kommen. Ob der Pfad auf einen bestimmten Dateieintrag oder ein Verzeichnis zeigt, liegt dabei natürlich im eigenen Ermessen.

Objektinstanzen und „Symbolische Links“

Das ganze Potential der Layer wird aber erst dann ausgespielt, wenn nicht nur Ordner und Dateien dort „abgelegt“ werden, sondern wenn direkt Java Objekte dort registriert werden. Ähnlich wie auch beim Standardmechanismus zu den Java Services kann man ein bestimmtes Klassenobjekt vom Laufzeitsystem erzeugen lassen und darauf zugreifen. Allerdings lässt sich das Objekt auf vielfältigere Art erzeugen als nur über einen Standardkonstruktor. Auch lassen sich durch das „position“ Attribut eine Reihenfolge der Objekte definieren 4.

Jeder <file>-Eintrag in der Layer mit der Endung .instance wird als „Objekt“ behandelt. Ist der „Dateiname“ dabei ein vollsändiger Klassenpfad (mit Bindestrichen statt Punkten), so wird wie bei den Services einfach der Standardkonstruktor der Klasse verwendet um eine Instanz zu erzeugen. Mit dem Attribut instanceCreate lässt sich dieser Mechanismus aber auch verändern. Durch ein newvalue könnte man zum Beispiel eine komplett andere Klasse als im Dateinamen angegeben dazu verwenden um die Instanz zu erzeugen.

Detailierter kann man die Generierung aber mit einem methodvalue 5 gestallten. Hierbei können auch die anderen Attribute des <file> Eintrags ausgewertet werden um eine noch „bessere“ Instanz zu erzeugen.

Eine weitere Besonderheit ist die Endung .shadow für einen <file>-Eintrag. Dies ist mit einer „Symbolischen Verknüpfung“ im Dateisystem vergleichbar. Es stellt nur eine Referenz dar auf eine andere Objekt-Instanz. Diese Instanz wird aber nicht kopiert sondern ist die gleiche Instanz. Ein Beispiel hierfür sind die Action Instanzen. Sie werden in der Regel nur einmal unter den Pfad /Actions/ abgelegt und dann im Menü und auch den Toolbars durch einen .shadow-Eintrag referenziert. Damit sind die Actions tatsächlich Singletons und haben automatisch den gleichen Status im Menü und auch den Toolbars.

Diesen Artikel könnte man noch beliebig weiter ausführen, wahrscheinlich ließe sich ein ganzes Buch darüber schreiben, aber das würde den Umfang hier sprengen. Bei Fragen darf die Kommentarfunktion unten aber gerne genutzt werden.

Notes:

  1. Auch wenn die Inhalte noch kompliziert und komplex genug sind
  2. z.B. die IDE selbst
  3. In diesem Fall also die NetBeans Rich Client Platform
  4. So definiert und sortiert NetBeans selbst zum Beispiel die Menüeinträge über diesen Mechanismus.
  5. Siehe dazu auch den Artikel „Möglichkeiten einer methodvalue Implementierung“ hier im Blog

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.