Java Getriebe

Java und NetBeans

Aus Alt mach Neu – ProjectConverter

Wir arbeiten bei uns in der „WZL Gear Toolbox“ mit der „Project API“ von NetBeans um verschiedene Simulationsansätze und -Programme einfacher verwalten zu können. Von Zeit zu Zeit kommt es dabei vor, dass sich die Programme oder die Konzepte der Simulationen ändern und wir neue Projekttypen definieren müssen und alte verwerfen. Je nach Alter der Programme haben sich beim Enduser allerdings mit der Zeit einige Projekte angesammelt, die er eigentlich gerne weiter nutzen würde. In vielen Fällen sind die einzugebenden Daten im alten wie im neuen Projekt gleich oder ähnlich. Ein Zahnrad zum Beispiel wird hat immer das Eingabedatum „Zähnezahl“.

Ändert sich die „Projekt-ID“ 1 eines Projektes nicht, so kann man sich ganz gut mit einem ProjectOpenedHook helfen, der alle notwendigen Änderungen an den Dateien vornimmt, bevor NetBeans das Projekt in der „Projects“ Liste anzeigt. Ändert sich die ID allerdings, tauchen die alten Projekte nicht im „Projekt öffnen“-Dialog der Anwendung auf. Bisher haben wir dies durch eine eigene „Import old project“-Action gelöst, die über eigene „ToolboxProjectConverter“ Implementierungen die notwendigen Änderungen durchgeführt hat. Seit NetBeans 8.1 ist dieser Umweg nicht mehr notwendig, denn im Modul „Base Project UI API“ gibt es jetzt einen ProjectConvertor.

Dieser ProjectConvertor erlaubt es aus „unbekannten“ Ordnern ein Project zu erzeugen ohne dass dafür eine ProjectFactory existieren muss. Diese „Pseudoprojekte“ werden dann ganz normal im „Project Open“-Dialog angezeigt und der Endanwender bekommt den Unterschied gar nicht mit. Das Interface besteht nur aus der Methode

1
Result isProject(FileObject projectDirectory);

Diese überprüft, ob ein Verzeichnis in ein Projekt umgewandelt werden kann. An dieser Stelle wird noch keine tatsächlich Umwandlung vorgenommen. Im Result werden „displayName“ und „Icon“ definiert, die im Dateidialog angezeigt werden. Außerdem könnte man noch ein Lookup definieren um zum Beispiel Projektabhängigkeiten zu definieren. Es reicht aber auch Lookup.EMPTY zu übergeben.

Der weitaus spannendere Teil passiert in dem Callable<Project> das dem Result mitgegeben wird. Dieses Callback wird genau
dann aufgerufen, wenn der Endanwender eben dieses Projekt öffnen möchte. Die call Methode muss nun dafür sorgen, dass eine gültige Project Implementierung erzeugt wird, wie auch immer das geschieht. Man könnte einfach eine eigene Instanz erzeugen oder (wie wir) die Dateien in dem Verzeichnis so umschreiben, dass ein anderes gültiges Projekt dabei herauskommt, wie es die aktuelle Anwendung auch neu erzeugen würde. Wenn man für das alte und das neue Projekt das gleiche Projekticon verwendet merkt der Endanwender die Umwandlung in der Regel gar nicht.

Meine Implementierung des Callable sieht (fast) immer so oder so ähnlich aus

1
2
3
4
5
6
7
8
9
@Override
public Project call() throws Exception
{
  if(convertProject(projectDirectory))
  {
    return ProjectManager.getDefault().findProject(projectDirectory);
  }
  return null;
}

Die convertProject bearbeitet die alte Projektstruktur und wandelt sie in ein Projektverzeichnis um, welches von der aktuellen „WZL Gear Toolbox“ als normales Projekt erkannt wird. Die Methode liefert zum einen ein boolean über den Erfolg oder Misserfolg zurück und wirft zum anderen auch eine IOException. Diese wird vom NetBeans ProjectConverter noch mal gesondert behandelt. Hat alles geklappt wird das Projekt über den Standardmechanismus der „Project API“, sprich dem ProjectManager, erzeugt.

Zuletzt noch ein kleiner Hinweis zu Annotation @ProjectConvertor.Registration und dort speziell zu dessen Parameter requiredPattern: Die JavaDocs schweigen sich (noch?) dazu aus, was dieser Parameter eigentlich genau macht. Der Text

the required file(s) regular expression

half mir nicht direkt weiter. Ein Blick in die Quellen verrät allerdings, dass hier ein Patternmatching mit den Namen aller direkter Kindelemente des Verzeichnisses durchgeführt wird. Man kann hier also nicht in weitere Unterverzeichnisse schauen oder den Inhalt einer Datei betrachtet. Nur, wenn zu diesem Pattern auch eine Datei oder ein Verzeichnis gefunden wurde wird auch die Methode isProject der Implementierung aufgerufen.

Notes:

  1. Also der „type“, der in der „project.xml“ steht

Schreibe einen Kommentar

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