Projektmigrationen erweitern

Da Faktor-IPS ständig weiter entwickelt wird, ist bei einem Versionswechsel oft auch eine Migration der bestehenden Projekte notwendig. Zu diesem Zweck kann im Kontextmenü eines Projekts die Migration aufgerufen werden.

Ob eine Migration notwendig ist, wird mit Hilfe der .ipsproject-Datei gesteuert. Darin ist hinterlegt, für welche Version das Projekt aktuell konfiguriert ist. Wenn in einer neuen Faktor-IPS-Version eine Migrationsstrategie für diese neue Version vorhanden ist, muss diese aufgerufen werden, da sonst das einwandfreie Funktionieren der Projekte nicht gewährleistet ist.

Mit einem eigenen Plugin kann das Faktor-IPS-Migrationsframework um eigene Migrationsstrategien erweitert werden. Diese Migrationen können z.B. dazu verwendet werden, um Produktprojekte auf eine neue Modellversion zu migrieren. Beispielsweise könnte eine Produktmigration notwendig werden, wenn im Modell ein neues Attribut eingeführt wurde und in den bestehenden Produkten abhängig von bestimmten Faktoren unterschiedliche initial andere Werte eingestellt werden sollen.

Vorbereitungen

Um eine eigene Migration entwickeln zu können, muss ein eigenes Eclipse-Plugin entwickelt und ausgeliefert werden. Das Plugin benötigt mindestens eine Abhängigkeit auf das Faktor-IPS Core Plug-In org.faktorips.devtools.core.

Überblick Architektur

Für eine eigene Migration wird zunächst ein Versionsmanager benötigt. Dieser wird einmal implementiert und legt fest, für welche Feature-ID Migrationen vorhanden sind. Für jeden Versionsmanager wird es in der.ipsproject-Datei einen Eintrag geben, der festlegt, welche Version dieses Features aktuell verwendet wird.

Ein Versionsmanager verwaltet mehrere Migrationsstrategien. Eine Migrationsstrategie ist immer für die Migration von einer Version auf die nächste zuständig. Will man über mehrere Versionen gleichzeitig migrieren, werden alle notwendigen Migrationsstrategien der Reihe nach ausgeführt.

Versionsmanager

Wenn kein eigener Versionsmanager entwickelt werden soll, kann einfach der ExtendableVersionManager verwendet werden. Dieser spezielle Versionsmanager verwendet einfach alle Migrationen, die unter dem Extension Point org.faktorips.devtools.model.ipsMigrationOperation im gleichen Plugin registriert sind. Außerdem wird die für die Migration zu Grunde gelegte Version aus dem Plugin verwendet.

Folgender Eintrag ist in der plugin.xml-Datei notwendig:

<extension point="org.faktorips.devtools.core.faktorIpsFeatureVersionManager">
    <faktorIpsFeatureVersionManager
          class="org.faktorips.devtools.core.model.versionmanager.ExtendableVersionManager"
          featureId="%feature ID%"
          id="%ID des Versionsmanager%"
          requiredForAllProjects="true">
    </faktorIpsFeatureVersionManager>
</extension>

Unter dem Attribut requiredForAllProjects kann eingestellt werden, ob alle Projekte im Workspace die Feature-ID und die Version eingetragen haben müssen. Ist dieses Attribute auf „false“ gesetzt, wird kein Fehler angezeigt, wenn der Eintrag für dieses Feature fehlt.

Migrationsoperation

Wurde der ExtendableVersionManager verwendet, können Migrationen über org.faktorips.devtools.core.ipsMigrationOperation registriert werden. Der Versionsmanager wird alle Migrationen verwenden, die im gleichen Plugin registriert wurden.

Eine einzelne Migrationsoperation muss auf jeden Fall von der abstrakten Klasse AbstractIpsProjectMigrationOperation abgeleitet werden. Hilfreich sind auch die weiteren abstrakten Basisklassen, vor allem DefaultMigration.

Zur Registrierung in der plugin.xml-Datei muss außerdem eine Factory implementiert werden, die vom Interface IIpsProjectMigrationOperationFactory ableitet. Die Factory kann z.B. als innere Klasse in der eigentlichen Migration angelegt werden.

Im folgenden Ausschnitt aus der plugin.xml-Datei wird gezeigt, wie die Migration für Faktor-IPS 21.6 registriert wurde.

<extension point="org.faktorips.devtools.core.ipsMigrationOperation">
    <migrationOperation
          class="org.faktorips.devtools.core.internal.migrationextensions.Migration_21_6_0$Factory"
          targetVersion="21.6.0">
</extension>

Wird die DefaultMigration verwendet, muss lediglich die Methode migrate(IIpsSrcFile srcFile) überschrieben werden. Diese Methode wird für jedes IIpsSrcFile einmal aufgerufen. Innerhalb der Methode können beliebige Änderungen an dem IpsObject in dem Sourcefile vorgenommen werden. Änderungen am Objekt dürfen nicht selbst gespeichert werden. Das Migrationsframework wird die Datei zum richtigen Zeitpunkt schreiben.

Attributsumbenennung

Seit Version 25.1 gibt es eine spezielle Hilfsklasse für Attributsumbenennungen: org.faktorips.devtools.core.migration.MigrationForChangedAttribute. Diese Migration wird komfortabel über Java-Records konfiguriert. Der Record ChangedAttribute erhält dabei den qualifiedName des Typs (Vertrags- oder Produkt-Teilklasse) sowie den alten und den neuen Namen des Attributs.

public class ChangedAttributeMigrationFactory implements IIpsProjectMigrationOperationFactory {

    @Override
    public AbstractIpsProjectMigrationOperation createIpsProjectMigrationOperation(IIpsProject ipsProject, String featureId) {
        // Verwende die Modellversion hier, diese Version ist unabhängig von der Faktor-IPS Version.
        return new MigrationForChangedAttribute(ipsProject, featureId, "1.0.1",
                "Diese Migration benennt alle Attribute von xyzA zu xyzB um.",
                new ChangedAttribute("base.Vertrag", "AttributeA", "AttributeB"),
                new ChangedAttribute("base.Produkt", "ProduktAttributeA", "ProduktAttributeB"));
    }
}

Zusätzlich zeigt der Migrationsdialog nun neben der Version auch die featureId an, um dem Benutzer anzuzeigen, welche Migration für welche Version durchgeführt wird.

Utils

Als weitere nützliche Hilfe bietet sich die ManifestUtil-Klasse an. Hier können beispielsweise die Versionen für abhängige Plugin-Versionen im MANIFEST.MF des zu migrierenden Projekts angepasst werden.