Ein Programm für die schrittweise Projekterstellung ist ein Objekt, das die Ressourcen in einem Projekt auf eine Weise verarbeitet, die durch das Erstellungsprogramm selbst definiert wird. Programme für die schrittweise Projekterstellung werden häufig zur Umwandlung einer Ressource in eine Ressource oder ein Artefakt eines anderen Typs eingesetzt.
Plug-ins ergänzen die Plattform durch Programme für die schrittweise Projekterstellung, um spezielle Ressourcenumwandlungen zu implementieren. Das JDT-Plug-in (Java Development Tooling - Java-Entwicklungstools), das zusammen mit der Plattform-SDK zur Verfügung gestellt wird, definiert beispielsweise ein Programm für die schrittweise Projekterstellung, mit dem eine Java-Quellendatei immer dann in eine Klassendatei kompiliert wird, wenn eine Datei in einem Java-Projekt hinzugefügt oder geändert wird. Außerdem berechnet dieses Programm alle anderen Dateien erneut, die von der Änderung betroffen sind.
Die Plattform definiert zwei Erstellungstypen:
Schrittweise Erstellungen werden mit einem Delta für die Ressourcenänderung vorgenommen. Das Delta gibt den Reineffekt aller Ressourcenänderungen seit der letzten Erstellung des Projekts durch das Erstellungsprogramm an. Dieses Delta ähnelt dem Delta, das innerhalb von Ereignissen für eine Ressourcenänderung verwendet wird.
Erstellungsprogramme können am besten durch Beispiele veranschaulicht werden. JDT (Java Development Tooling - Java-Entwicklungstools) stellt einen Java-Compiler zur Verfügung, der durch ein Programm zur schrittweisen Erstellung von Java-Projekten gesteuert wird und Dateien erneut kompiliert, die von Änderungen betroffen sind. Wenn eine vollständige Erstellung ausgelöst wird, werden alle Dateien .java im Projekt kompiliert. Alle festgestellten Kompilierungsprobleme werden hierbei als Problemmarkierungen für die betroffenen Dateien .java hinzugefügt. Wird eine schrittweise Erstellung ausgelöst, kompiliert das Erstellungsprogramm selektiv die Dateien .java erneut, die hinzugefügt, geändert oder auf andere Weise betroffen und im Ressourcendelta beschrieben sind, und aktualisiert ggfs. die Problemmarkierungen wie erforderlich. Alle Dateien .class oder Markierungen, die nicht länger gültig sind, werden entfernt.
Die schrittweise Erstellung bietet offensichtliche Leistungsvorteile bei Projekten, die Hunderte oder Tausende Ressourcen enthalten, von denen die meisten an einem bestimmten Zeitpunkt unverändert bleiben.
Die technische Herausforderung besteht bei der schrittweisen Erstellung darin, genau zu ermitteln, welche Ressourcen erneut erstellt werden müssen. Der durch das Java-Erstellungsprogramm verwaltete interne Status enthält beispielweise Informationen wie ein Abhängigkeitsdiagramm sowie eine Liste der gemeldeten Kompilierungsprobleme. Anhand dieser Informationen werden bei einer schrittweisen Erstellung die Klassen identifiziert, die als Reaktion auf eine Änderung in einer Java-Ressource erneut kompiliert werden müssen.
Obwohl die Basisstruktur für die Erstellung in der Plattform definiert ist, wird die tatsächliche Arbeit durch das Plug-in ausgeführt. Muster für die Implementierung von komplexen Programmen für eine schrittweise Erstellung würden den Rahmen dieser Beschreibung sprengen, da die Implementierung vom Entwurf des spezifischen Erstellungsprogramms abhängig ist.
Ein Erstellungsprogramm kann durch eine der folgenden Aktionen explizit aufgerufen werden:
In der Praxis löst der Workbench-Benutzer eine Erstellung aus, indem die entsprechenden Befehle im Menü der Ressourcensicht "Navigator" ausgewählt werden.
Programme für die schrittweise Projekterstellung werden durch die Plattform außerdem implizit bei einer automatischen Erstellung aufgerufen. Wenn die entsprechende Option aktiviert ist, wird bei jeder Änderung des Arbeitsbereichs eine automatische Erstellung vorgenommen.
Am Erweiterungspunkt org.eclipse.core.resources.builders kann die Plattform durch ein Programm für die schrittweise Projekterstellung ergänzt werden. Die folgende Definition zeigt, wie das hypothetische Plug-in com.example.builders ein Programm für die schrittweise Projekterstellung hinzufügen könnte.
<extension id="mybuilder" name="My Sample Builder" point="org.eclipse.core.resources.builders"> <builder <run class="com.example.builders.BuilderExample"> <parameter name="optimize" value="true" /> <parameter name="comment" value="Builder-Kommentar" /> </run> </builder> </extension>
Die im Erweiterungspunkt angegebene Klasse muss die Plattformklasse IncrementalProjectBuilder erweitern.
public class BuilderExample extends IncrementalProjectBuilder { IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { // Hier muss die Erstellungslogik eingefügt werden return null; } protected void startupOnInitialize() { // Hier muss die Logik zur Initialisierung des Erstellungsprogramms eingefügt werden } }
Der Erstellungsprozess beginnt mit der Methode build(), die Informationen über den angeforderten Typ der Erstellung enthält (FULL_BUILD, INCREMENTAL_BUILD oder AUTO_BUILD). Falls eine schrittweise Erstellung (INCREMENTAL_BUILD) angefordert wurde, wird ein Ressourcendelta zur Verfügung gestellt, um die Änderungen zu beschreiben, die seit der letzten Erstellung an den Ressourcen des Projekts vorgenommen wurden. Das folgende Snippet definiert die Methode build() genauer.
protected IProject[] build(int kind, Map args, IProgressMonitor monitor throws CoreException { if (kind == IncrementalProjectBuilder.FULL_BUILD) { fullBuild(monitor); } else { IResourceDelta delta = getDelta(getProject()); if (delta == null) { fullBuild(monitor); } else { incrementalBuild(delta, monitor); } } return null; }
Manchmal kommt es vor, dass bei der Erstellung des Projekts X ein Erstellungsprogramm Informationen zu Änderungen benötigt, die in einem anderen Projekt (Y) vorgenommen wurden (z. B. wenn eine Java-Klasse in X eine durch Y bereitgestellte Schnittstelle implementiert).Bei der Erstellung von X kann ein Delta für Y zur Verfügung gestellt werden, indem die Methode getDelta(Y) aufgerufen wird. Um sicherzustellen, dass die Plattform solche Deltas zur Verfügung stellen kann, muss das Erstellungsprogramm für X die Abhängigkeit zwischen X und Y deklariert haben. Dies erfolgt durch die Rückgabe eines Bereichs aus einem früheren Aufruf der Methode build(), der Y enthält. Falls ein Erstellungsprogramm keine Abhängigkeiten enthält, kann einfach Null zurückgegeben werden. Weitere Informationen finden Sie unter IncrementalProjectBuilder.
Die Logik, die zur Verarbeitung einer vollständigen Erstellung benötigt wird, ist für das Plug-in spezifisch. Sie kann die Involvierung jeder Ressource im Projekt enthalten (wenn die Erstellung für ein Projekt ausgelöst wurde), oder sogar andere Projekte untersuchen, wenn zwischen Projekten Abhängigkeiten vorliegen. Das folgende Snippet ist ein Vorschlag dafür, wie eine vollständige Erstellung implementiert werden könnte.
protected void fullBuild(final IProgressMonitor monitor) throws CoreException { try { getProject().accept(new MyBuildVisitor()); } catch (CoreException e) { } }
Das Erstellungsprogramm würde in diesem Fall die Erstellung für die spezifische Ressource ausführen (und den Wert "true" (= wahr) für das Berücksichtigen aller untergeordneten Ressourcen angeben).
class MyBuildVisitor implements IResourceVisitor { public boolean visit(IResource res) { // Angegebene Ressource erstellen. // TRUE für die weitere Berücksichtigung von untergeordneten Ressourcen zurückgeben. return true; } }
Dieser Prozess wird fortgesetzt, bis die gesamte Ressourcenstruktur durchgearbeitet wurde.
Bei der Ausführung einer schrittweisen Erstellung arbeiten Sie nicht mit dem gesamten Projekt, sondern nur mit einem Ressourcenänderungsdelta.
protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException { // Arbeit wird durch visitor übernommen. delta.accept(new MyBuildDeltaVisitor()); }
Bei einer schrittweisen Erstellung ist zu beachten, dass das Aufrufen der Erstellung mit Hilfe einer Baumstruktur der Ressourcendeltas und nicht mit einer Baumstruktur aller Ressourcen erfolgt.
Dieser Prozess wird fortgesetzt, bis die komplette Baumstruktur der Ressourcendeltas durchgearbeitet wurde. Der spezifische Typ der Änderungen entspricht etwa den unter Listener-Funktion für Ressourcenänderungen implementieren beschriebenen Änderungen. Ein wichtiger Unterschied ist jedoch, dass Sie bei Programmen für die schrittweise Projekterstellung mit einem Ressourcendelta arbeiten, das auf einem bestimmten Projekt und nicht auf dem gesamten Arbeitsbereich basiert.
Damit für das jeweilige Projekt ein Erstellungsprogramm verfügbar ist, muss es in die Erstellungsspezifikation für das Projekt aufgenommen werden. Die Erstellungsspezifikation eines Projekts ist eine Liste der Befehle, die bei der Erstellung des Projekts nacheinander ausgeführt werden müssen. Jeder Befehl benennt ein einzelnes Programm für die schrittweise Projekterstellung.
Das folgende Snippet fügt ein neues Erstellungsprogramm als erstes Erstellungsprogramm zur vorhandenen Liste der Erstellungsprogramme hinzu.
IProjectDescription desc = project.getDescription(); ICommand[] commands = desc.getBuildSpec(); boolean found = false; for (int i = 0; i < commands.length; ++i) { if (commands[i].getBuilderName().equals(BUILDER_ID)) { found = true; break; } } if (!found) { // Erstellungsprogramm zum Projekt hinzufügen ICommand command = desc.newCommand(); command.setBuilderName(BUILDER_ID); ICommand[] newCommands = new ICommand[commands.length + 1]; // Programm vor anderen Erstellungsprogrammen hinzufügen System.arraycopy(commands, 0, newCommands, 1, commands.length); newCommands[0] = command; desc.setBuildSpec(newCommands); project.setDescription(desc, null); }
Die Konfiguration des Erstellungsprogramms für ein Projekt muss nur ein Mal vorgenommen werden. Dies erfolgt für gewöhnlich im Rahmen der Projekterstellung.