English Documentation

Extending Project Migrations

As Faktor-IPS is continuously developed, a migration of existing projects is often necessary when switching versions. For this purpose, the migration can be invoked from the context menu of a project.

Whether a migration is necessary is controlled by the .ipsproject file. This file contains the version for which the project is currently configured. If a migration strategy for this new version exists in a new Faktor-IPS version, it must be executed to ensure that projects function correctly.

With a custom plugin, the Faktor-IPS migration framework can be extended with custom migration strategies. These migrations can be used, for example, to migrate product projects to a new model version. For instance, a product migration might be necessary if a new attribute is introduced in the model, and different initial values need to be set in the existing products depending on certain factors.

Preparations

To develop a custom migration, a custom Eclipse plugin must be developed and delivered. The plugin requires at least a dependency on the Faktor-IPS Core Plugin org.faktorips.devtools.core.

Architecture Overview

For a custom migration, a version manager is required. This version manager is implemented once and defines which feature ID migrations are available. For each version manager, there will be an entry in the .ipsproject file specifying which version of the feature is currently in use.

A version manager manages multiple migration strategies. A migration strategy is always responsible for migrating from one version to the next. If migrating across multiple versions, all necessary migration strategies will be executed sequentially.

Version Manager

If a custom version manager is not needed, the ExtendableVersionManager can be used. This special version manager simply uses all migrations registered under the extension point org.faktorips.devtools.model.ipsMigrationOperation in the same plugin. Additionally, the version used for the migration is taken from the plugin.

The following entry is required in the plugin.xml file:

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

The attribute requiredForAllProjects can be set to determine whether all projects in the workspace must have the feature ID and version recorded. If this attribute is set to false, no error will be displayed if the entry for this feature is missing.

Migration Operation

When using the ExtendableVersionManager, migrations can be registered via org.faktorips.devtools.core.ipsMigrationOperation extension point. The version manager will use all migrations registered in the same plugin.

An individual migration operation must extend the abstract class AbstractIpsProjectMigrationOperation. Other abstract base classes, particularly DefaultMigration, can also be helpful.

Additionally, a factory must be implemented and registered in the plugin.xml file. The factory must implement the IIpsProjectMigrationOperationFactory interface. The factory can be created as an inner class within the actual migration class.

The following snippet from the plugin.xml file shows how the migration for Faktor-IPS 21.6 was registered.

<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>

If using DefaultMigration, you only need to override the migrate(IIpsSrcFile srcFile) method. This method is called once for each IIpsSrcFile. Within the method, any changes can be made to the IpsObject in the source file. However, changes to the object should not be saved directly. The migration framework will write the file at the appropriate time.

Attribute Renaming

Since version 25.1, there is a special helper class for attribute renaming: org.faktorips.devtools.core.migration.MigrationForChangedAttribute. This migration is conveniently configured using Java records. The ChangedAttribute record receives the qualifiedName of the type (policy- or product-component-type) as well as the old and new name of the attribute.

public class ChangedAttributeMigrationFactory implements IIpsProjectMigrationOperationFactory {

    @Override
    public AbstractIpsProjectMigrationOperation createIpsProjectMigrationOperation(IIpsProject ipsProject, String featureId) {
        // Use the model version here; this version is independent of the Faktor-IPS version.
        return new MigrationForChangedAttribute(ipsProject, featureId, "1.0.1",
                "This migration renames all attributes from xyzA to xyzB.",
                new ChangedAttribute("base.Contract", "AttributeA", "AttributeB"),
                new ChangedAttribute("base.Product", "ProductAttributeA", "ProductAttributeB"));
    }
}

Additionally, the migration dialog now displays the featureId along with the version to show the user which migration is running for which version.

Utils

The ManifestUtil class is also a useful utility. For example, it can be used to adjust the versions for dependent plugin versions in the MANIFEST.MF of the project being migrated.