diff --git a/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationEmbeddedStorage.java b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationEmbeddedStorage.java
new file mode 100644
index 0000000..52bdb7e
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationEmbeddedStorage.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore;
+
+import java.nio.file.Path;
+import java.util.Objects;
+
+import org.eclipse.store.afs.nio.types.NioFileSystem;
+import org.eclipse.store.storage.embedded.types.EmbeddedStorage;
+import org.eclipse.store.storage.embedded.types.EmbeddedStorageFoundation;
+import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager;
+import org.eclipse.store.storage.types.Storage;
+import org.eclipse.store.storage.types.StorageConfiguration;
+
+import software.xdev.micromigration.migrater.MicroMigrater;
+
+
+/**
+ * Provides static utility calls to create the {@link MigrationEmbeddedStorageManager} for updateable datastores.
+ * Basically a wrapper for the utility class {@link EmbeddedStorage}.
+ */
+public final class MigrationEmbeddedStorage
+{
+ /**
+ * Creates a {@link MigrationEmbeddedStorageManager} with the given {@link MicroMigrater}. Uses the
+ * {@link EmbeddedStorageFoundation#New()} configuration for the actual {@link EmbeddedStorageManager}.
+ * Warning "resource" is suppressed because it is used and closed in the
+ * {@link MigrationEmbeddedStorageManager}.
+ *
+ * @param migrater which is used as source for the migration scripts
+ * @return the created storage manager with the given migrater
+ */
+ @SuppressWarnings("java:S2095")
+ public static MigrationEmbeddedStorageManager start(final MicroMigrater migrater)
+ {
+ Objects.requireNonNull(migrater);
+ return new MigrationEmbeddedStorageManager(
+ createStorageManager(),
+ migrater
+ ).start();
+ }
+
+ /**
+ * Creates a {@link MigrationEmbeddedStorageManager} with the given {@link MicroMigrater}. Uses the
+ * {@link EmbeddedStorageFoundation#New()} configuration for the actual {@link EmbeddedStorageManager}.
+ *
Warning "resource" is suppressed because it is used and closed in the
+ * {@link MigrationEmbeddedStorageManager}.
+ *
+ * @param storageDirectory is used as the base directory for the datastore
+ * @param migrater which is used as source for the migration scripts
+ * @return the created storage manager with the given migrater
+ */
+ @SuppressWarnings("java:S2095")
+ public static MigrationEmbeddedStorageManager start(
+ final Path storageDirectory,
+ final MicroMigrater migrater
+ )
+ {
+ Objects.requireNonNull(migrater);
+ Objects.requireNonNull(storageDirectory);
+
+ return new MigrationEmbeddedStorageManager(
+ createStorageManager(storageDirectory),
+ migrater
+ ).start();
+ }
+
+ private static EmbeddedStorageManager createStorageManager(final Path storageDirectory)
+ {
+ final NioFileSystem fileSystem = NioFileSystem.New();
+ return EmbeddedStorageFoundation.New()
+ .setConfiguration(
+ StorageConfiguration.Builder()
+ .setStorageFileProvider(
+ Storage.FileProviderBuilder(fileSystem)
+ .setDirectory(fileSystem.ensureDirectoryPath(storageDirectory.toAbsolutePath().toString()))
+ .createFileProvider()
+ )
+ .createConfiguration()
+ )
+ .createEmbeddedStorageManager();
+ }
+
+ private static EmbeddedStorageManager createStorageManager()
+ {
+ return EmbeddedStorageFoundation.New()
+ .setConfiguration(
+ StorageConfiguration.Builder().createConfiguration()
+ )
+ .createEmbeddedStorageManager();
+ }
+
+ private MigrationEmbeddedStorage()
+ {
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationEmbeddedStorageManager.java b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationEmbeddedStorageManager.java
new file mode 100644
index 0000000..61eddee
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationEmbeddedStorageManager.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore;
+
+import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager;
+
+import software.xdev.micromigration.migrater.MicroMigrater;
+import software.xdev.micromigration.version.Versioned;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager;
+
+
+/**
+ * Specific implementation of the {@link VersionAgnosticMigrationEmbeddedStorageManager} for one specific version.
+ * @see VersionAgnosticMigrationEmbeddedStorageManager
+ */
+public class MigrationEmbeddedStorageManager
+ extends VersionAgnosticMigrationEmbeddedStorageManager
+{
+ /**
+ * @param nativeManager which will be used as the underlying storage manager. Almost all methods are only rerouted
+ * to this native manager. Only {@link #start()}, {@link #root()} and {@link #setRoot(Object)}
+ * are intercepted and a {@link Versioned} is placed between the requests.
+ * @param migrater which is used as source for the migration scripts
+ */
+ public MigrationEmbeddedStorageManager(
+ final EmbeddedStorageManager nativeManager,
+ final MicroMigrater migrater
+ )
+ {
+ super(new TunnelingEmbeddedStorageManager(nativeManager), migrater);
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationManager.java b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationManager.java
new file mode 100644
index 0000000..34edbf3
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationManager.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore;
+
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager;
+
+import software.xdev.micromigration.migrater.MicroMigrater;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.version.Versioned;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationManager;
+
+
+/**
+ * Specific implementation of the {@link VersionAgnosticMigrationManager}.
+ *
+ * @see VersionAgnosticMigrationManager
+ */
+public class MigrationManager extends VersionAgnosticMigrationManager
+{
+ /**
+ * Much more complicated constructor than
+ * {@link MigrationManager#MigrationManager(Versioned, MicroMigrater, EmbeddedStorageManager)}
+ *
+ * @param currentVersionGetter which supplies the current version of the object to update.
+ * @param currentVersionSetter which sets the new version of the object in some membervariable. This Consumer is
+ * not
+ * supposed to store the version, but only save it in some membervariable to be stored
+ * after.
+ * @param currentVersionStorer which is supposed to store the new version of the object somewhere in the datastore.
+ * @param migrater does the actual migration with the given {@link VersionAgnosticMigrationScript}
+ * @param storageManager for the {@link VersionAgnosticMigrationScript}s to use. Is not used for the storing
+ * of the new version.
+ */
+ public MigrationManager(
+ final Supplier currentVersionGetter,
+ final Consumer currentVersionSetter,
+ final Consumer currentVersionStorer,
+ final MicroMigrater migrater,
+ final EmbeddedStorageManager storageManager
+ )
+ {
+ super(
+ currentVersionGetter,
+ currentVersionSetter,
+ currentVersionStorer,
+ migrater,
+ new MigrationEmbeddedStorageManager(storageManager, migrater));
+ }
+
+ /**
+ * Simple Constructor.
+ *
+ * @param versionedObject which provides getter and setter for the current version. This object will be stored
+ * after
+ * the {@link VersionAgnosticMigrationScript}s are executed.
+ * @param migrater does the actual migration with the given {@link VersionAgnosticMigrationScript}
+ * @param storageManager for the {@link VersionAgnosticMigrationScript}s to use. Is not used for the storing of
+ * the
+ * new version.
+ */
+ public MigrationManager(
+ final Versioned versionedObject,
+ final MicroMigrater migrater,
+ final EmbeddedStorageManager storageManager
+ )
+ {
+ super(versionedObject, migrater, new MigrationEmbeddedStorageManager(storageManager, migrater));
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationScript.java b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationScript.java
new file mode 100644
index 0000000..111e008
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/MigrationScript.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore;
+
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+
+
+/**
+ * Interface for scripts to migrate / update datastores.
+ *
+ * One script is supposed to bring a datastore from a lower version to the target version. After the
+ * {@link VersionAgnosticMigrationScript#migrate(Context)} method is called, the target version is reached.
+ *
+ * This is a shorthand for {@link VersionAgnosticMigrationScript}
+ */
+public interface MigrationScript extends VersionAgnosticMigrationScript
+{
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/TunnelingEmbeddedStorageManager.java b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/TunnelingEmbeddedStorageManager.java
new file mode 100644
index 0000000..1bb2984
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/eclipsestore/TunnelingEmbeddedStorageManager.java
@@ -0,0 +1,418 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore;
+
+import java.nio.ByteBuffer;
+import java.util.Objects;
+import java.util.function.Predicate;
+
+import org.eclipse.serializer.afs.types.AFile;
+import org.eclipse.serializer.collections.types.XGettingEnum;
+import org.eclipse.serializer.persistence.binary.types.Binary;
+import org.eclipse.serializer.persistence.types.PersistenceManager;
+import org.eclipse.serializer.persistence.types.PersistenceRootsView;
+import org.eclipse.serializer.persistence.types.PersistenceTypeDictionaryExporter;
+import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager;
+import org.eclipse.store.storage.types.Database;
+import org.eclipse.store.storage.types.StorageConfiguration;
+import org.eclipse.store.storage.types.StorageConnection;
+import org.eclipse.store.storage.types.StorageEntityCacheEvaluator;
+import org.eclipse.store.storage.types.StorageEntityTypeExportFileProvider;
+import org.eclipse.store.storage.types.StorageEntityTypeExportStatistics;
+import org.eclipse.store.storage.types.StorageEntityTypeHandler;
+import org.eclipse.store.storage.types.StorageLiveFileProvider;
+import org.eclipse.store.storage.types.StorageRawFileStatistics;
+import org.eclipse.store.storage.types.StorageTypeDictionary;
+
+import software.xdev.micromigration.version.Versioned;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticTunnelingEmbeddedStorageManager;
+
+
+/**
+ * Wrapper class for the {@link EmbeddedStorageManager} interface.
+ *
+ * It simply relays all the commands to the contained {@link EmbeddedStorageManager}.
+ * @see VersionAgnosticTunnelingEmbeddedStorageManager
+ */
+public class TunnelingEmbeddedStorageManager
+ implements
+ EmbeddedStorageManager,
+ VersionAgnosticTunnelingEmbeddedStorageManager
+{
+ /**
+ * The underlying, actual EmbeddedStorageManager
+ */
+ protected final EmbeddedStorageManager nativeManager;
+
+ /**
+ * @param nativeManager which will be used as the underlying storage manager. All methods are only rerouted to this
+ * native manager. Only {@link #start()}, {@link #root()} and {@link #setRoot(Object)} are
+ * intercepted and a {@link Versioned} is placed between the requests.
+ */
+ public TunnelingEmbeddedStorageManager(
+ final EmbeddedStorageManager nativeManager
+ )
+ {
+ Objects.requireNonNull(nativeManager);
+ this.nativeManager = nativeManager;
+ }
+
+ ////////////////////////////////////////////////////////////////
+ // Simply forward all the methods
+ ////////////////////////////////////////////////////////////////
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#start}
+ */
+ @Override
+ public TunnelingEmbeddedStorageManager start()
+ {
+ this.nativeManager.start();
+ return this;
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#root}
+ */
+ @Override
+ public Object root()
+ {
+ return this.nativeManager.root();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#setRoot(Object)}
+ */
+ @Override
+ public Object setRoot(final Object newRoot)
+ {
+ return this.nativeManager.setRoot(newRoot);
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#storeRoot()}
+ */
+ @Override
+ public long storeRoot()
+ {
+ return this.nativeManager.storeRoot();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#configuration()}
+ */
+ @Override
+ public StorageConfiguration configuration()
+ {
+ return this.nativeManager.configuration();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#typeDictionary()}
+ */
+ @Override
+ public StorageTypeDictionary typeDictionary()
+ {
+ return this.nativeManager.typeDictionary();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#shutdown()}
+ */
+ @Override
+ public boolean shutdown()
+ {
+ return this.nativeManager.shutdown();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#close()}
+ */
+ @Override
+ public void close()
+ {
+ this.nativeManager.close();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#createConnection()}
+ */
+ @Override
+ public StorageConnection createConnection()
+ {
+ return this.nativeManager.createConnection();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#viewRoots()}
+ */
+ @Override
+ public PersistenceRootsView viewRoots()
+ {
+ return this.nativeManager.viewRoots();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#database()}
+ */
+ @Override
+ public Database database()
+ {
+ return this.nativeManager.database();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#isAcceptingTasks()}
+ */
+ @Override
+ public boolean isAcceptingTasks()
+ {
+ return this.nativeManager.isAcceptingTasks();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#isRunning()}
+ */
+ @Override
+ public boolean isRunning()
+ {
+ return this.nativeManager.isRunning();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#isStartingUp()}
+ */
+ @Override
+ public boolean isStartingUp()
+ {
+ return this.nativeManager.isStartingUp();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#isShuttingDown()}
+ */
+ @Override
+ public boolean isShuttingDown()
+ {
+ return this.nativeManager.isShuttingDown();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#checkAcceptingTasks()}
+ */
+ @Override
+ public void checkAcceptingTasks()
+ {
+ this.nativeManager.checkAcceptingTasks();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#initializationTime()}
+ */
+ @Override
+ public long initializationTime()
+ {
+ return this.nativeManager.initializationTime();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#operationModeTime()}
+ */
+ @Override
+ public long operationModeTime()
+ {
+ return this.nativeManager.operationModeTime();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#isActive()}
+ */
+ @Override
+ public boolean isActive()
+ {
+ return this.nativeManager.isActive();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#issueGarbageCollection(long)}
+ */
+ @Override
+ public boolean issueGarbageCollection(final long nanoTimeBudget)
+ {
+ return this.nativeManager.issueGarbageCollection(nanoTimeBudget);
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#issueFileCheck(long)}
+ */
+ @Override
+ public boolean issueFileCheck(final long nanoTimeBudget)
+ {
+ return this.nativeManager.issueFileCheck(nanoTimeBudget);
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#issueCacheCheck(long, StorageEntityCacheEvaluator)}
+ */
+ @Override
+ public boolean issueCacheCheck(final long nanoTimeBudget, final StorageEntityCacheEvaluator entityEvaluator)
+ {
+ return this.nativeManager.issueCacheCheck(nanoTimeBudget, entityEvaluator);
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#createStorageStatistics}
+ */
+ @Override
+ public StorageRawFileStatistics createStorageStatistics()
+ {
+ return this.nativeManager.createStorageStatistics();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#exportChannels(StorageLiveFileProvider)}
+ */
+ @Override
+ public void exportChannels(final StorageLiveFileProvider fileProvider, final boolean performGarbageCollection)
+ {
+ this.nativeManager.exportChannels(fileProvider, performGarbageCollection);
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#exportTypes(StorageEntityTypeExportFileProvider)}
+ */
+ @Override
+ public StorageEntityTypeExportStatistics exportTypes(
+ final StorageEntityTypeExportFileProvider exportFileProvider,
+ final Predicate super StorageEntityTypeHandler> isExportType)
+ {
+ return this.nativeManager.exportTypes(exportFileProvider, isExportType);
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#importFiles(XGettingEnum)}
+ */
+ @Override
+ public void importFiles(final XGettingEnum importFiles)
+ {
+ this.nativeManager.importFiles(importFiles);
+ }
+
+ @Override
+ public void importData(final XGettingEnum xGettingEnum)
+ {
+ this.nativeManager.importData(xGettingEnum);
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#persistenceManager()}
+ */
+ @Override
+ public PersistenceManager persistenceManager()
+ {
+ return this.nativeManager.persistenceManager();
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#store(Object)}
+ */
+ @Override
+ public long store(final Object instance)
+ {
+ return EmbeddedStorageManager.super.store(instance);
+ }
+
+ @Override
+ public EmbeddedStorageManager getNativeStorageManager()
+ {
+ return this.nativeManager;
+ }
+
+ /**
+ * Simply tunneling the call through to the {@link EmbeddedStorageManager} given through the constructor. Please
+ * see
+ * {@link EmbeddedStorageManager#issueFullBackup(StorageLiveFileProvider, PersistenceTypeDictionaryExporter)}
+ */
+ @Override
+ public void issueFullBackup(
+ final StorageLiveFileProvider targetFileProvider,
+ final PersistenceTypeDictionaryExporter typeDictionaryExporter)
+ {
+ this.nativeManager.issueFullBackup(targetFileProvider, typeDictionaryExporter);
+ }
+
+ @Override
+ public void issueTransactionsLogCleanup()
+ {
+ this.nativeManager.issueTransactionsLogCleanup();
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/migrater/AbstractMigrater.java b/micro-migration/src/main/java/software/xdev/micromigration/migrater/AbstractMigrater.java
new file mode 100644
index 0000000..bbf0d71
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/migrater/AbstractMigrater.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater;
+
+import java.time.Clock;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.TreeSet;
+import java.util.function.Consumer;
+
+import software.xdev.micromigration.notification.ScriptExecutionNotificationWithScriptReference;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager;
+
+
+/**
+ * Provides the basic functionality to apply {@link VersionAgnosticMigrationScript}s to a datastore.
+ */
+public abstract class AbstractMigrater implements MicroMigrater
+{
+ private final List> notificationConsumers =
+ new ArrayList<>();
+ private Clock clock = Clock.systemDefaultZone();
+
+ @Override
+ public void registerNotificationConsumer(
+ final Consumer notificationConsumer)
+ {
+ this.notificationConsumers.add(notificationConsumer);
+ }
+
+ @Override
+ public > MigrationVersion migrateToNewest(
+ final MigrationVersion fromVersion,
+ final E storageManager,
+ final Object root
+ )
+ {
+ Objects.requireNonNull(fromVersion);
+ Objects.requireNonNull(storageManager);
+
+ final TreeSet extends VersionAgnosticMigrationScript, ?>> sortedScripts = this.getSortedScripts();
+ if(!sortedScripts.isEmpty())
+ {
+ return this.migrateToVersion(
+ fromVersion,
+ this.getSortedScripts().last().getTargetVersion(),
+ storageManager,
+ root
+ );
+ }
+ return fromVersion;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public > MigrationVersion migrateToVersion(
+ final MigrationVersion fromVersion,
+ final MigrationVersion targetVersion,
+ final E storageManager,
+ final Object objectToMigrate
+ )
+ {
+ Objects.requireNonNull(fromVersion);
+ Objects.requireNonNull(targetVersion);
+ Objects.requireNonNull(storageManager);
+
+ MigrationVersion updateVersionWhichWasExecuted = fromVersion;
+ for(final VersionAgnosticMigrationScript, ?> script : this.getSortedScripts())
+ {
+ final VersionAgnosticMigrationScript, E> castedScript = (VersionAgnosticMigrationScript, E>)script;
+ if(MigrationVersion.COMPARATOR.compare(fromVersion, script.getTargetVersion()) < 0
+ && MigrationVersion.COMPARATOR.compare(script.getTargetVersion(), targetVersion) <= 0)
+ {
+ LocalDateTime startDate = null;
+ final MigrationVersion versionBeforeUpdate = updateVersionWhichWasExecuted;
+ if(!this.notificationConsumers.isEmpty())
+ {
+ startDate = LocalDateTime.now(this.clock);
+ }
+ updateVersionWhichWasExecuted =
+ this.migrateWithScript(castedScript, storageManager, objectToMigrate);
+ if(!this.notificationConsumers.isEmpty())
+ {
+ final ScriptExecutionNotificationWithScriptReference scriptNotification =
+ new ScriptExecutionNotificationWithScriptReference(
+ script,
+ versionBeforeUpdate,
+ updateVersionWhichWasExecuted,
+ startDate,
+ LocalDateTime.now(this.clock)
+ );
+ this.notificationConsumers.forEach(consumer -> consumer.accept(scriptNotification));
+ }
+ }
+ }
+ return updateVersionWhichWasExecuted;
+ }
+
+ @SuppressWarnings("unchecked")
+ private > MigrationVersion migrateWithScript(
+ final VersionAgnosticMigrationScript script,
+ final E storageManager,
+ final Object objectToMigrate
+ )
+ {
+ final T castedObjectToMigrate = (T)objectToMigrate;
+ script.migrate(new Context<>(castedObjectToMigrate, storageManager));
+ return script.getTargetVersion();
+ }
+
+ /**
+ * Checks if the given {@link VersionAgnosticMigrationScript} is not already registered in the
+ * {@link #getSortedScripts()}.
+ *
+ * @param scriptToCheck It's target version is checked, if it is not already registered.
+ * @throws VersionAlreadyRegisteredException if script is already registered.
+ */
+ protected void checkIfVersionIsAlreadyRegistered(final VersionAgnosticMigrationScript, ?> scriptToCheck)
+ {
+ // Check if same version is not already registered
+ for(final VersionAgnosticMigrationScript, ?> alreadyRegisteredScript : this.getSortedScripts())
+ {
+ if(MigrationVersion.COMPARATOR.compare(
+ alreadyRegisteredScript.getTargetVersion(),
+ scriptToCheck.getTargetVersion()) == 0)
+ {
+ // Two scripts with the same version are not allowed to get registered.
+ throw new VersionAlreadyRegisteredException(
+ alreadyRegisteredScript.getTargetVersion(),
+ alreadyRegisteredScript,
+ scriptToCheck
+ );
+ }
+ }
+ }
+
+ /**
+ * Change used clock for notifications from {@link #registerNotificationConsumer(Consumer)}.
+ *
+ * @param clock is used when a
+ * {@link software.xdev.micromigration.notification.ScriptExecutionNotificationWithoutScriptReference}
+ * is created
+ * @return self
+ */
+ public AbstractMigrater withClock(final Clock clock)
+ {
+ this.clock = clock;
+ return this;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/migrater/ExplicitMigrater.java b/micro-migration/src/main/java/software/xdev/micromigration/migrater/ExplicitMigrater.java
new file mode 100644
index 0000000..29f1170
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/migrater/ExplicitMigrater.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater;
+
+import java.util.TreeSet;
+
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+
+
+/**
+ * Contains all the available scripts to migrate the datastore to a certain version.
+ *
+ * This class needs explicit scripts which are then included in the migration process.
+ */
+public class ExplicitMigrater extends AbstractMigrater
+{
+ private final TreeSet> sortedScripts = new TreeSet<>(
+ VersionAgnosticMigrationScript.COMPARATOR);
+
+ /**
+ * @param scripts are all the scripts that are executed, if the current version is lower than this of the
+ * script
+ * Versions of the scripts must be unique. That means that no version is allowed multiple times in
+ * the migrater.
+ * @throws VersionAlreadyRegisteredException if two scripts have the same version
+ */
+ @SuppressWarnings("PMD.UseArraysAsList")
+ public ExplicitMigrater(final VersionAgnosticMigrationScript, ?>... scripts)
+ {
+ for(final VersionAgnosticMigrationScript, ?> script : scripts)
+ {
+ this.checkIfVersionIsAlreadyRegistered(script);
+ this.sortedScripts.add(script);
+ }
+ }
+
+ @Override
+ public TreeSet> getSortedScripts()
+ {
+ return this.sortedScripts;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/migrater/MicroMigrater.java b/micro-migration/src/main/java/software/xdev/micromigration/migrater/MicroMigrater.java
new file mode 100644
index 0000000..7cf747e
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/migrater/MicroMigrater.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater;
+
+import java.util.TreeSet;
+import java.util.function.Consumer;
+
+import software.xdev.micromigration.notification.ScriptExecutionNotificationWithScriptReference;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager;
+
+
+/**
+ * Executes all the available scripts to migrate the datastore to a certain version.
+ */
+public interface MicroMigrater
+{
+ /**
+ * @return all the contained {@link VersionAgnosticMigrationScript}s, sorted by their {@link MigrationVersion}
+ * ascending.
+ */
+ @SuppressWarnings("java:S1452")
+ TreeSet extends VersionAgnosticMigrationScript, ?>> getSortedScripts();
+
+ /**
+ * Executes all the scripts that are available to the migrater. Only scripts with a higher target version than the
+ * given fromVersion are executed. Scripts are executed one after another from the lowest to the highest
+ * version.
+ *
+ * Example:
+ * Current version is 1.0.0 Scripts for v1.1.0, v2.0.0 and v1.2.1 are available Scripts are chain executed
+ * like v1.1.0 then v1.2.1 then v2.0.0
+ *
+ * @param fromVersion is the current version of the datastore. Scripts for lower versions then the fromVersion
+ * are not executed.
+ * @param storageManager is relayed to the scripts {@link VersionAgnosticMigrationScript#migrate(Context)} method.
+ * This way the script can call
+ * {@link VersionAgnosticMigrationEmbeddedStorageManager#store(Object)} or another method on
+ * the storage manager.
+ * @param root is relayed to the scripts {@link VersionAgnosticMigrationScript#migrate(Context)} method.
+ * This way the script can change something within the root object.
+ * @param the {@link VersionAgnosticMigrationEmbeddedStorageManager} which contains the migrating
+ * object
+ * @return the target version of the last executed script
+ */
+ > MigrationVersion migrateToNewest(
+ MigrationVersion fromVersion,
+ E storageManager,
+ Object root
+ );
+
+ /**
+ * Executes all the scripts that are available to the migrater until the given targetVersion is reached. Only
+ * scripts with a higher target version than the given fromVersion are executed. Scripts are executed one after
+ * another from the lowest to the highest version.
+ *
+ * Example:
+ * Current version is 1.0.0 Scripts for v1.1.0, v2.0.0 and v1.2.1 are available Scripts are chain executed
+ * like v1.1.0 then v1.2.1 then v2.0.0
+ *
+ * @param fromVersion is the current version of the datastore. Scripts for lower versions then the fromVersion
+ * are not executed.
+ * @param targetVersion is the highest allowed script version. Scripts which have a higher version won't be
+ * exectued.
+ * @param storageManager is relayed to the scripts {@link VersionAgnosticMigrationScript#migrate(Context)} method.
+ * This way the script can call EmbeddedStorageManager#store or another method on the
+ * storage
+ * manager.
+ * @param objectToMigrate is relayed to the scripts {@link VersionAgnosticMigrationScript#migrate(Context)} method.
+ * This way the script can change something within the object to migrate.
+ * @param the {@link VersionAgnosticMigrationEmbeddedStorageManager} which contains the migrating
+ * object
+ * @return the target version of the last executed script
+ */
+ > MigrationVersion migrateToVersion(
+ MigrationVersion fromVersion,
+ MigrationVersion targetVersion,
+ E storageManager,
+ Object objectToMigrate
+ );
+
+ /**
+ * Registers a callback to take action when a script is executed.
+ *
+ * @param notificationConsumer is executed when a script is used from this migrater.
+ */
+ void registerNotificationConsumer(
+ Consumer notificationConsumer);
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/migrater/VersionAlreadyRegisteredException.java b/micro-migration/src/main/java/software/xdev/micromigration/migrater/VersionAlreadyRegisteredException.java
new file mode 100644
index 0000000..f10ce22
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/migrater/VersionAlreadyRegisteredException.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater;
+
+import java.util.Objects;
+
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+/**
+ * Exception that should be used if two scripts with the same version exist.
+ */
+@SuppressWarnings({"java:S1948", "java:S1452"})
+public class VersionAlreadyRegisteredException extends RuntimeException
+{
+ /**
+ * The already registered script with the same version
+ */
+ private final MigrationVersion alreadyRegisteredVersion;
+ /**
+ * The version of the already registered script
+ */
+ private final VersionAgnosticMigrationScript, ?> alreadyRegisteredScript;
+ /**
+ * The script with the same version as {@link #alreadyRegisteredScript}, which should be registered as well
+ */
+ private final VersionAgnosticMigrationScript, ?> newScriptToRegister;
+
+ /**
+ * @param alreadyRegisteredVersion The version of the already registered script
+ * @param alreadyRegisteredScript The already registered script with the same version
+ * @param newScriptToRegister The script with the same version as alreadyRegisteredScript, which should be
+ * registered as well
+ */
+ public VersionAlreadyRegisteredException(
+ final MigrationVersion alreadyRegisteredVersion,
+ final VersionAgnosticMigrationScript, ?> alreadyRegisteredScript,
+ final VersionAgnosticMigrationScript, ?> newScriptToRegister
+ )
+ {
+ super("Version " + alreadyRegisteredVersion.toString()
+ + " is already registered. Versions must be unique within the migrater.");
+ this.alreadyRegisteredVersion = Objects.requireNonNull(alreadyRegisteredVersion);
+ this.alreadyRegisteredScript = Objects.requireNonNull(alreadyRegisteredScript);
+ this.newScriptToRegister = Objects.requireNonNull(newScriptToRegister);
+ }
+
+ /**
+ * @return the version of the already registered script
+ */
+ public MigrationVersion getAlreadyRegisteredVersion()
+ {
+ return this.alreadyRegisteredVersion;
+ }
+
+ /**
+ * @return the already registered script with the same version
+ */
+ public VersionAgnosticMigrationScript, ?> getAlreadyRegisteredScript()
+ {
+ return this.alreadyRegisteredScript;
+ }
+
+ /**
+ * @return the script with the same version as {@link #getAlreadyRegisteredScript()}, which should be registered as
+ * well
+ */
+ public VersionAgnosticMigrationScript, ?> getNewScriptToRegister()
+ {
+ return this.newScriptToRegister;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/migrater/reflection/ReflectiveMigrater.java b/micro-migration/src/main/java/software/xdev/micromigration/migrater/reflection/ReflectiveMigrater.java
new file mode 100644
index 0000000..49210df
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/migrater/reflection/ReflectiveMigrater.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.TreeSet;
+
+import software.xdev.micromigration.migrater.AbstractMigrater;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+
+
+/**
+ * Contains all the available scripts to migrate the datastore to a certain version.
+ *
+ * Searches all implementation of {@link VersionAgnosticMigrationScript} in the specified package and it's the sub
+ * packages.
+ *
+ *
+ * Reflection source: https://stackoverflow.com/a/520344
+ *
+ * @author AB
+ */
+public class ReflectiveMigrater extends AbstractMigrater
+{
+ private static final String CLASS_EXTENSION = ".class";
+
+ private final TreeSet> sortedScripts = new TreeSet<>(
+ VersionAgnosticMigrationScript.COMPARATOR);
+
+ /**
+ * @param packagePath defines the package in which {@link VersionAgnosticMigrationScript}s will be searched. Also
+ * searches through all sub packages of packagePath
+ * @throws ScriptInstantiationException if a class in the given package could not be instantiated
+ */
+ @SuppressWarnings("unchecked")
+ public ReflectiveMigrater(final String packagePath)
+ {
+ getClasses(packagePath)
+ .stream()
+ .filter(c -> !Modifier.isAbstract(c.getModifiers()))
+ .filter(VersionAgnosticMigrationScript.class::isAssignableFrom)
+ .map(c -> (Class extends VersionAgnosticMigrationScript>)c)
+ .map(this::instantiateClass)
+ .forEach(instantiateScript -> {
+ this.checkIfVersionIsAlreadyRegistered(instantiateScript);
+ this.sortedScripts.add(instantiateScript);
+ });
+ }
+
+ @SuppressWarnings("rawtypes")
+ private VersionAgnosticMigrationScript, ?> instantiateClass(
+ final Class extends VersionAgnosticMigrationScript> scriptClass)
+ {
+ try
+ {
+ return scriptClass.getDeclaredConstructor().newInstance();
+ }
+ catch(final InstantiationException
+ | IllegalAccessException
+ | IllegalArgumentException
+ | InvocationTargetException
+ | NoSuchMethodException
+ | SecurityException e
+ )
+ {
+ throw new ScriptInstantiationException("Could not instantiate class " + scriptClass.getName(), e);
+ }
+ }
+
+ /**
+ * Scans all classes accessible from the context class loader which belong to the given package and subpackages.
+ *
+ * @param packageName The base package
+ * @return The classes
+ */
+ private static List> getClasses(final String packageName)
+ {
+ try
+ {
+ final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ assert classLoader != null;
+ final String path = packageName.replace('.', '/');
+ final Enumeration resources = classLoader.getResources(path);
+ final List dirs = new ArrayList<>();
+ while(resources.hasMoreElements())
+ {
+ final URL resource = resources.nextElement();
+ dirs.add(new File(resource.getFile()));
+ }
+ final ArrayList> classes = new ArrayList<>();
+ for(final File directory : dirs)
+ {
+ classes.addAll(findClasses(directory, packageName));
+ }
+ return classes;
+ }
+ catch(final ClassNotFoundException e)
+ {
+ throw new IllegalStateException("Unable to find class", e);
+ }
+ catch(final IOException ioe)
+ {
+ throw new UncheckedIOException(ioe);
+ }
+ }
+
+ /**
+ * Recursive method used to find all classes in a given directory and subdirs.
+ *
+ * @param directory The base directory
+ * @param packageName The package name for classes found inside the base directory
+ * @return The classes
+ */
+ private static List> findClasses(final File directory, final String packageName)
+ throws ClassNotFoundException
+ {
+ if(!directory.exists())
+ {
+ return new ArrayList<>();
+ }
+
+ final List> classes = new ArrayList<>();
+ for(final File file : directory.listFiles())
+ {
+ if(file.isDirectory())
+ {
+ assert !file.getName().contains(".");
+ classes.addAll(findClasses(file, packageName + "." + file.getName()));
+ }
+ else if(file.getName().endsWith(CLASS_EXTENSION))
+ {
+ classes.add(Class.forName(
+ packageName + '.' + file.getName()
+ .substring(0, file.getName().length() - CLASS_EXTENSION.length())));
+ }
+ }
+ return classes;
+ }
+
+ @Override
+ public TreeSet> getSortedScripts()
+ {
+ return this.sortedScripts;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/migrater/reflection/ScriptInstantiationException.java b/micro-migration/src/main/java/software/xdev/micromigration/migrater/reflection/ScriptInstantiationException.java
new file mode 100644
index 0000000..3377adf
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/migrater/reflection/ScriptInstantiationException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection;
+
+/**
+ * Holds information about exceptions if a script class can not be instantiated.
+ */
+public class ScriptInstantiationException extends RuntimeException
+{
+ /**
+ * @param message for the exception
+ * @param cause of the exception
+ */
+ public ScriptInstantiationException(final String message, final Throwable cause)
+ {
+ super(message, cause);
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/notification/AbstractScriptExecutionNotification.java b/micro-migration/src/main/java/software/xdev/micromigration/notification/AbstractScriptExecutionNotification.java
new file mode 100644
index 0000000..0513fd5
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/notification/AbstractScriptExecutionNotification.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.notification;
+
+import java.time.LocalDateTime;
+
+import software.xdev.micromigration.migrater.MicroMigrater;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+/**
+ * Contains data about the execution of a script by a {@link MicroMigrater}.
+ */
+public abstract class AbstractScriptExecutionNotification
+{
+ private final MigrationVersion sourceVersion;
+ private final MigrationVersion targetVersion;
+ private final LocalDateTime startDate;
+ private final LocalDateTime endDate;
+
+ /**
+ * @param sourceVersion original version of the object before executing the script
+ * @param targetVersion version of the object after executing the script
+ * @param startDate time when the script was started
+ * @param endDate time when the script has finished
+ */
+ protected AbstractScriptExecutionNotification(
+ final MigrationVersion sourceVersion,
+ final MigrationVersion targetVersion,
+ final LocalDateTime startDate,
+ final LocalDateTime endDate
+ )
+ {
+ super();
+ this.sourceVersion = sourceVersion;
+ this.targetVersion = targetVersion;
+ this.startDate = startDate;
+ this.endDate = endDate;
+ }
+
+ /**
+ * @return the original version of the object before executing the script
+ */
+ public MigrationVersion getSourceVersion()
+ {
+ return this.sourceVersion;
+ }
+
+ /**
+ * @return the version of the object after executing the script
+ */
+ public MigrationVersion getTargetVersion()
+ {
+ return this.targetVersion;
+ }
+
+ /**
+ * @return the time when the script was started
+ */
+ public LocalDateTime getStartDate()
+ {
+ return this.startDate;
+ }
+
+ /**
+ * @return time when the script has finished
+ */
+ public LocalDateTime getEndDate()
+ {
+ return this.endDate;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/notification/ScriptExecutionNotificationWithScriptReference.java b/micro-migration/src/main/java/software/xdev/micromigration/notification/ScriptExecutionNotificationWithScriptReference.java
new file mode 100644
index 0000000..8affdf4
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/notification/ScriptExecutionNotificationWithScriptReference.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.notification;
+
+import java.time.LocalDateTime;
+
+import software.xdev.micromigration.migrater.MicroMigrater;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+/**
+ * Contains data about the execution of a script by a {@link MicroMigrater}.
+ */
+public class ScriptExecutionNotificationWithScriptReference extends AbstractScriptExecutionNotification
+{
+ private final VersionAgnosticMigrationScript, ?> executedScript;
+
+ /**
+ * @param executedScript script that was executed
+ * @param sourceVersion original version of the object before executing the script
+ * @param targetVersion version of the object after executing the script
+ * @param startDate time when the script was started
+ * @param endDate time when the script has finished
+ */
+ public ScriptExecutionNotificationWithScriptReference(
+ final VersionAgnosticMigrationScript, ?> executedScript,
+ final MigrationVersion sourceVersion,
+ final MigrationVersion targetVersion,
+ final LocalDateTime startDate,
+ final LocalDateTime endDate
+ )
+ {
+ super(
+ sourceVersion,
+ targetVersion,
+ startDate,
+ endDate
+ );
+ this.executedScript = executedScript;
+ }
+
+ /**
+ * @return the script that was executed
+ */
+ @SuppressWarnings("java:S1452")
+ public VersionAgnosticMigrationScript, ?> getExecutedScript()
+ {
+ return this.executedScript;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/notification/ScriptExecutionNotificationWithoutScriptReference.java b/micro-migration/src/main/java/software/xdev/micromigration/notification/ScriptExecutionNotificationWithoutScriptReference.java
new file mode 100644
index 0000000..cacf6f9
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/notification/ScriptExecutionNotificationWithoutScriptReference.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.notification;
+
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+
+/**
+ * Same as {@link ScriptExecutionNotificationWithScriptReference} but instead of referencing
+ * the {@link VersionAgnosticMigrationScript} directly, only the name of the script is
+ * extracted through the class name.
+ *
+ * "Why?!" - If you want to persist say a history of your applied scripts in your database and
+ * you reference your scripts directly, these classes are referenced in your datastore.
+ * That shouldn't be a problem. Except when you refactor or delete these scripts.
+ * Usually what's really important is the name of the script.
+ */
+public class ScriptExecutionNotificationWithoutScriptReference extends AbstractScriptExecutionNotification
+{
+ private final String executedScriptName;
+
+ /**
+ * @param originalNotification where the reference to the script is deleted and the class name is extracted.
+ */
+ public ScriptExecutionNotificationWithoutScriptReference(
+ final ScriptExecutionNotificationWithScriptReference originalNotification)
+ {
+ super(
+ originalNotification.getSourceVersion(),
+ originalNotification.getTargetVersion(),
+ originalNotification.getStartDate(),
+ originalNotification.getEndDate()
+ );
+ this.executedScriptName = originalNotification.getExecutedScript().getClass().getSimpleName();
+ }
+
+ /**
+ * @return the name of the script that was extracted.
+ */
+ public String getExecutedScriptName()
+ {
+ return this.executedScriptName;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/scripts/Context.java b/micro-migration/src/main/java/software/xdev/micromigration/scripts/Context.java
new file mode 100644
index 0000000..9525de7
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/scripts/Context.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.scripts;
+
+/**
+ * Container that holds necessary information for the execution of an {@link VersionAgnosticMigrationScript}
+ */
+public class Context
+{
+ private final T migratingObject;
+ private final E storageManager;
+
+ /**
+ * @param migratingObject that must be migrated to a new version
+ * @param storageManager where the migratingObject is stored
+ */
+ public Context(
+ final T migratingObject,
+ final E storageManager
+ )
+ {
+ super();
+ this.migratingObject = migratingObject;
+ this.storageManager = storageManager;
+ }
+
+ /**
+ * @return the current object where the migration is executed upon
+ */
+ public T getMigratingObject()
+ {
+ return this.migratingObject;
+ }
+
+ /**
+ * @return the responsible storage manager for the migrating object
+ */
+ public E getStorageManager()
+ {
+ return this.storageManager;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/scripts/ReflectiveVersionMigrationScript.java b/micro-migration/src/main/java/software/xdev/micromigration/scripts/ReflectiveVersionMigrationScript.java
new file mode 100644
index 0000000..b2d1511
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/scripts/ReflectiveVersionMigrationScript.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.scripts;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager;
+
+
+/**
+ * Script which creates the target version of the script through the class name.
+ *
+ * Class name has to be in the scheme:
+ *
+ * vM_Classname vM_m_Classname vM_m_m_Classname
+ *
+ * Where v
is short for version and is a constant (just a char),
+ * M
is a integer for the major version,
+ * m
is a integer for the minor version
+ * Classname
is a custom String that the user can choose.
+ * This scheme can basically be extended infinetly. For example: v1_1_2_2_MyUpdateScript
+ *
+ * Therefore the character _
can only be used as a seperator of versions and may not be used for other
+ * purposes.
+ *
+ * If the class name has the wrong format, an {@link Error} is thrown.
+ */
+public abstract class ReflectiveVersionMigrationScript<
+ T,
+ E extends VersionAgnosticMigrationEmbeddedStorageManager, ?>>
+ implements VersionAgnosticMigrationScript
+{
+ private static final char PREFIX = 'v';
+ private static final String VERSION_SEPERATOR = "_";
+ private static final String WRONG_FORMAT_ERROR_MESSAGE =
+ "Script has invalid class name. Either rename the class to a valid script class name, or implement method "
+ + "getTargetVersion().";
+
+ private final MigrationVersion version;
+
+ /**
+ * @throws Error if the class name has the wrong format
+ */
+ protected ReflectiveVersionMigrationScript()
+ {
+ this.version = this.createTargetVersionFromClassName();
+ }
+
+ private MigrationVersion createTargetVersionFromClassName()
+ {
+ final String implementationClassName = this.getClass().getSimpleName();
+ if(PREFIX != implementationClassName.charAt(0))
+ {
+ throw new IllegalArgumentException(WRONG_FORMAT_ERROR_MESSAGE);
+ }
+ final String implementationClassNameWithoutPrefix = implementationClassName.substring(1);
+ final String[] classNameParts = implementationClassNameWithoutPrefix.split(VERSION_SEPERATOR);
+ if(classNameParts.length < 2)
+ {
+ throw new IllegalArgumentException(WRONG_FORMAT_ERROR_MESSAGE);
+ }
+ try
+ {
+ final List versionNumbers = new ArrayList<>();
+ for(int i = 0; i < classNameParts.length - 1; i++)
+ {
+ versionNumbers.add(Integer.parseInt(classNameParts[i]));
+ }
+ return new MigrationVersion(versionNumbers);
+ }
+ catch(final NumberFormatException e)
+ {
+ throw new IllegalArgumentException(WRONG_FORMAT_ERROR_MESSAGE, e);
+ }
+ }
+
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return this.version;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/scripts/SimpleMigrationScript.java b/micro-migration/src/main/java/software/xdev/micromigration/scripts/SimpleMigrationScript.java
new file mode 100644
index 0000000..fee2487
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/scripts/SimpleMigrationScript.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.scripts;
+
+import java.util.function.Consumer;
+
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager;
+
+
+/**
+ * Provides a simple way to create a migration script with the necessary version and {@link Consumer}.
+ */
+public class SimpleMigrationScript>
+ extends SimpleTypedMigrationScript
+{
+ /**
+ * @param targetVersion to which the script is updating the object
+ * @param consumer which consumes the object and updates it to the target version
+ */
+ public SimpleMigrationScript(
+ final MigrationVersion targetVersion,
+ final Consumer> consumer
+ )
+ {
+ super(targetVersion, consumer);
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/scripts/SimpleTypedMigrationScript.java b/micro-migration/src/main/java/software/xdev/micromigration/scripts/SimpleTypedMigrationScript.java
new file mode 100644
index 0000000..1394f8b
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/scripts/SimpleTypedMigrationScript.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.scripts;
+
+import java.util.Objects;
+import java.util.function.Consumer;
+
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager;
+
+
+/**
+ * Provides a simple way to create a migration script with the necessary version and {@link Consumer}.
+ */
+public class SimpleTypedMigrationScript>
+ implements VersionAgnosticMigrationScript
+{
+ private final MigrationVersion version;
+ private final Consumer> consumer;
+
+ /**
+ * @param version of the datastore after this script is executed
+ * @param consumer which is executed to reach the given datastore version
+ */
+ public SimpleTypedMigrationScript(
+ final MigrationVersion version,
+ final Consumer> consumer
+ )
+ {
+ Objects.requireNonNull(version);
+ Objects.requireNonNull(consumer);
+ this.version = version;
+ this.consumer = consumer;
+ }
+
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return this.version;
+ }
+
+ @Override
+ public void migrate(final Context context)
+ {
+ this.consumer.accept(context);
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/scripts/VersionAgnosticMigrationScript.java b/micro-migration/src/main/java/software/xdev/micromigration/scripts/VersionAgnosticMigrationScript.java
new file mode 100644
index 0000000..1e455c5
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/scripts/VersionAgnosticMigrationScript.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.scripts;
+
+import java.util.Comparator;
+
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager;
+
+
+/**
+ * Interface for scripts to migrate / update datastores.
+ *
+ * One script is supposed to bring a datastore from a lower version to the target version. After the
+ * {@link VersionAgnosticMigrationScript#migrate(Context)} method is called, the target version is reached.
+ */
+public interface VersionAgnosticMigrationScript>
+{
+ /**
+ * @return the version of the datastore after this script is executed.
+ */
+ MigrationVersion getTargetVersion();
+
+ /**
+ * Execute logic to migrate the given datastore to a newer version of the store. After executing the
+ * {@link #getTargetVersion()} is reached.
+ *
+ * @param context that holds necessary data for the migration
+ */
+ void migrate(Context context);
+
+ /**
+ * Provides a {@link Comparator} that compares the {@link #getTargetVersion()} of the given scripts
+ */
+ Comparator> COMPARATOR =
+ (o1, o2) -> MigrationVersion.COMPARATOR.compare(o1.getTargetVersion(), o2.getTargetVersion());
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/version/MigrationVersion.java b/micro-migration/src/main/java/software/xdev/micromigration/version/MigrationVersion.java
new file mode 100644
index 0000000..c5c9bae
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/version/MigrationVersion.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.version;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+
+/**
+ * Defines one version of the EclipseStore datastore.
+ */
+public class MigrationVersion
+{
+ private final int[] versions;
+
+ /**
+ * @param versions as integers. For example 1.0.2 would be an array of [1,0,2]
+ */
+ public MigrationVersion(final int... versions)
+ {
+ if(versions == null || versions.length == 0)
+ {
+ this.versions = new int[]{0};
+ }
+ else
+ {
+ this.versions = versions;
+ }
+ }
+
+ /**
+ * @param versionsAsList as integers. For example 1.0.2 would be a list of [1,0,2]
+ */
+ public MigrationVersion(final List versionsAsList)
+ {
+ if(versionsAsList == null || versionsAsList.isEmpty())
+ {
+ this.versions = new int[]{0};
+ }
+ else
+ {
+ final int[] versionsAsArray = new int[versionsAsList.size()];
+ for(int i = 0; i < versionsAsArray.length; i++)
+ {
+ versionsAsArray[i] = versionsAsList.get(i);
+ }
+ this.versions = versionsAsArray;
+ }
+ }
+
+ /**
+ * @return versions as an array of integers. For example 1.0.2 would be an array of [1,0,2]
+ */
+ public int[] getVersions()
+ {
+ return this.versions;
+ }
+
+ @Override
+ public String toString()
+ {
+ final StringBuilder sb = new StringBuilder("v");
+ for(final int version : this.versions)
+ {
+ sb.append(version).append('.');
+ }
+ sb.deleteCharAt(sb.length() - 1);
+ return sb.toString();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + Arrays.hashCode(this.versions);
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj)
+ {
+ if(this == obj)
+ {
+ return true;
+ }
+ if(obj == null)
+ {
+ return false;
+ }
+ if(this.getClass() != obj.getClass())
+ {
+ return false;
+ }
+ final MigrationVersion other = (MigrationVersion)obj;
+ return Arrays.equals(this.versions, other.versions);
+ }
+
+ /**
+ * Provides a {@link Comparator} that compares the {@link #getVersions()} of the given versions
+ */
+ public static final Comparator COMPARATOR =
+ Comparator.comparing(MigrationVersion::getVersions, Arrays::compare);
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/version/Versioned.java b/micro-migration/src/main/java/software/xdev/micromigration/version/Versioned.java
new file mode 100644
index 0000000..80436da
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/version/Versioned.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.version;
+
+/**
+ * Interface used by the MigrationManagers for easier versioning of objects.
+ */
+public interface Versioned
+{
+ /**
+ * @param version to set the current version of the object
+ */
+ void setVersion(MigrationVersion version);
+
+ /**
+ * @return the current version of the object
+ */
+ MigrationVersion getVersion();
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedAndKeeperOfHistory.java b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedAndKeeperOfHistory.java
new file mode 100644
index 0000000..37e85da
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedAndKeeperOfHistory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.version;
+
+import java.util.List;
+
+import software.xdev.micromigration.notification.ScriptExecutionNotificationWithoutScriptReference;
+
+/**
+ * Interface used by the MigrationManagers for easier versioning of objects
+ * and to keep and read the migration history.
+ */
+public interface VersionedAndKeeperOfHistory extends Versioned
+{
+ /**
+ * Adds the information about the executed script to the history book.
+ * @param executedScriptInformation information about the executed script
+ */
+ void addExecutedScript(ScriptExecutionNotificationWithoutScriptReference executedScriptInformation);
+
+ /**
+ * @return the complete migration history. That means information about every executed script.
+ */
+ List getMigrationHistory();
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedObject.java b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedObject.java
new file mode 100644
index 0000000..fe6e420
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedObject.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.version;
+
+import java.util.Objects;
+
+
+/**
+ * Simple container to hold a specific object and a correlating version for it.
+ *
+ * @param type of the object that's contained
+ */
+public class VersionedObject implements Versioned
+{
+ private MigrationVersion currentVersion;
+ private T actualObject;
+
+ /**
+ * @param actualObject set the actual object which is versioned
+ */
+ public VersionedObject(final T actualObject)
+ {
+ this.actualObject = actualObject;
+ this.currentVersion = new MigrationVersion(0);
+ }
+
+ @Override
+ public void setVersion(final MigrationVersion version)
+ {
+ Objects.requireNonNull(version);
+ this.currentVersion = version;
+ }
+
+ @Override
+ public MigrationVersion getVersion()
+ {
+ return this.currentVersion;
+ }
+
+ /**
+ * @param actualObject which is versioned
+ */
+ public void setObject(final T actualObject)
+ {
+ this.actualObject = actualObject;
+ }
+
+ /**
+ * @return the actual object which is versioned
+ */
+ public T getObject()
+ {
+ return this.actualObject;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.currentVersion.toString() + "\n" + this.actualObject;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedObjectWithHistory.java b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedObjectWithHistory.java
new file mode 100644
index 0000000..08e0360
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedObjectWithHistory.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.version;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import software.xdev.micromigration.notification.ScriptExecutionNotificationWithoutScriptReference;
+
+
+/**
+ * This class is inserted as the root of the datastore and contains only the current version, the actual
+ * root object and the history of executed scripts.
+ */
+public class VersionedObjectWithHistory extends VersionedObject implements VersionedAndKeeperOfHistory
+{
+ private final List migrationHistory;
+
+ /**
+ * @param actualRoot which is stored in the datastore and defined by the user
+ */
+ public VersionedObjectWithHistory(final Object actualRoot)
+ {
+ super(actualRoot);
+ this.migrationHistory = new ArrayList<>();
+ }
+
+ @Override
+ public void addExecutedScript(final ScriptExecutionNotificationWithoutScriptReference executedScriptInformation)
+ {
+ this.migrationHistory.add(Objects.requireNonNull(executedScriptInformation));
+ }
+
+ @Override
+ public List getMigrationHistory()
+ {
+ return this.migrationHistory;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedRoot.java b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedRoot.java
new file mode 100644
index 0000000..48f54c8
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedRoot.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.version;
+
+import java.util.Objects;
+
+
+/**
+ * This class is inserted as the root of the datastore and contains only the current version and the actual root
+ * object.
+ */
+public class VersionedRoot implements Versioned
+{
+ private MigrationVersion currentVersion;
+ private Object actualRoot;
+
+ /**
+ * @param actualRoot which is stored in the datastore and defined by the user
+ */
+ public VersionedRoot(final Object actualRoot)
+ {
+ this.actualRoot = actualRoot;
+ this.currentVersion = new MigrationVersion(0);
+ }
+
+ @Override
+ public void setVersion(final MigrationVersion version)
+ {
+ Objects.requireNonNull(version);
+ this.currentVersion = version;
+ }
+
+ @Override
+ public MigrationVersion getVersion()
+ {
+ return this.currentVersion;
+ }
+
+ /**
+ * @param actualRoot which is stored in the datastore and defined by the user
+ */
+ public void setRoot(final Object actualRoot)
+ {
+ this.actualRoot = actualRoot;
+ }
+
+ /**
+ * @return the actual root, that's defined by the user
+ */
+ public Object getRoot()
+ {
+ return this.actualRoot;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedRootWithHistory.java b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedRootWithHistory.java
new file mode 100644
index 0000000..bdbfc58
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/version/VersionedRootWithHistory.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.version;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import software.xdev.micromigration.notification.ScriptExecutionNotificationWithoutScriptReference;
+
+
+/**
+ * This class is inserted as the root of the datastore and contains only the current version, the actual root object
+ * and the history of executed scripts.
+ */
+public class VersionedRootWithHistory extends VersionedRoot implements VersionedAndKeeperOfHistory
+{
+ private final List migrationHistory;
+
+ /**
+ * @param actualRoot which is stored in the datastore and defined by the user
+ */
+ public VersionedRootWithHistory(final Object actualRoot)
+ {
+ super(actualRoot);
+ this.migrationHistory = new ArrayList<>();
+ }
+
+ @Override
+ public void addExecutedScript(final ScriptExecutionNotificationWithoutScriptReference executedScriptInformation)
+ {
+ this.migrationHistory.add(Objects.requireNonNull(executedScriptInformation));
+ }
+
+ /**
+ * @return the complete migration history. That means information about every executed script.
+ */
+ @Override
+ public List getMigrationHistory()
+ {
+ return this.migrationHistory;
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/versionagnostic/VersionAgnosticMigrationEmbeddedStorageManager.java b/micro-migration/src/main/java/software/xdev/micromigration/versionagnostic/VersionAgnosticMigrationEmbeddedStorageManager.java
new file mode 100644
index 0000000..a3a58f0
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/versionagnostic/VersionAgnosticMigrationEmbeddedStorageManager.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.versionagnostic;
+
+import java.util.List;
+import java.util.Objects;
+
+import software.xdev.micromigration.migrater.MicroMigrater;
+import software.xdev.micromigration.notification.ScriptExecutionNotificationWithoutScriptReference;
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.version.Versioned;
+import software.xdev.micromigration.version.VersionedRoot;
+import software.xdev.micromigration.version.VersionedRootWithHistory;
+
+
+/**
+ * Wrapper class for the {@link org.eclipse.store.storage.embedded.types.EmbeddedStorageManager} interface.
+ *
+ * Basically it intercepts storing the root object and places a {@link Versioned} in front of it. This means the root
+ * object of the datastore is then versioned. Internally uses the {@link VersionAgnosticMigrationManager} to do the
+ * actual migration.
+ *
+ * {@code VersionAgnostic} because it should be independent of the actual implementation used.
+ *
+ * @param class of itself to be able to return the actual class and not just a generic class
+ * @param The actually used EmbeddedStorageManager
+ */
+public abstract class VersionAgnosticMigrationEmbeddedStorageManager
+ implements AutoCloseable
+{
+ private final MicroMigrater migrater;
+ private VersionedRootWithHistory versionRoot;
+ private final VersionAgnosticTunnelingEmbeddedStorageManager tunnelingManager;
+
+ /**
+ * @param tunnelingManager which will be used as the underlying storage manager. Almost all methods are only
+ * rerouted to this native manager. Only {@link #start()}, {@link #root()} and
+ * {@link #setRoot(Object)} are intercepted and a {@link Versioned} is placed between the
+ * requests.
+ * @param migrater which is used as source for the migration scripts
+ */
+ protected VersionAgnosticMigrationEmbeddedStorageManager(
+ final VersionAgnosticTunnelingEmbeddedStorageManager tunnelingManager,
+ final MicroMigrater migrater
+ )
+ {
+ this.tunnelingManager = Objects.requireNonNull(tunnelingManager);
+ this.migrater = Objects.requireNonNull(migrater);
+ }
+
+ /**
+ * @return the native EmbeddedStorageManager
+ */
+ public E getNativeStorageManager()
+ {
+ return this.getTunnelingManager().getNativeStorageManager();
+ }
+
+ /**
+ * @return the used {@link VersionAgnosticTunnelingEmbeddedStorageManager}
+ */
+ protected VersionAgnosticTunnelingEmbeddedStorageManager getTunnelingManager()
+ {
+ return this.tunnelingManager;
+ }
+
+ /**
+ * Checks if the root object is of the instance of {@link Versioned}. If it is not, the root will be replaced with
+ * the versioned root and the actual root object will be put inside the versioned root.
+ *
+ * After starting the storage manager, all the available update scripts are executed in order until the newest
+ * version of the datastore is reached.
+ *
+ * @return itself
+ */
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ public T start()
+ {
+ this.tunnelingManager.start();
+ if(this.tunnelingManager.root() instanceof final VersionedRootWithHistory versionedRootWithHistory)
+ {
+ this.versionRoot = versionedRootWithHistory;
+ }
+ else
+ {
+ // Build VersionedRootWithHistory around actual root, set by user.
+ this.versionRoot = new VersionedRootWithHistory(this.tunnelingManager.root());
+ this.tunnelingManager.setRoot(this.versionRoot);
+ this.tunnelingManager.storeRoot();
+ }
+ new VersionAgnosticMigrationManager(
+ this.versionRoot,
+ this.migrater,
+ this
+ ).migrate(this.versionRoot.getRoot());
+ return (T)this;
+ }
+
+ /**
+ * @return current version that's managed
+ */
+ public MigrationVersion getCurrentVersion()
+ {
+ return this.versionRoot.getVersion();
+ }
+
+ /**
+ * @return the actual root object
+ */
+ public Object root()
+ {
+ return this.versionRoot.getRoot();
+ }
+
+ /**
+ * @return the actual root object
+ */
+ public List getMigrationHistory()
+ {
+ return this.versionRoot.getMigrationHistory();
+ }
+
+ /**
+ * Sets the actual root element (not the versioned root)
+ *
+ * @param newRoot to set
+ * @return the set object
+ */
+ public Object setRoot(final Object newRoot)
+ {
+ this.versionRoot.setRoot(newRoot);
+ return newRoot;
+ }
+
+ /**
+ * Stores the {@link VersionedRoot} and the actual root object.
+ *
+ * @return what EmbeddedStorageManager#storeRoot returns
+ */
+ public long storeRoot()
+ {
+ this.tunnelingManager.store(this.versionRoot);
+ return this.tunnelingManager.store(this.versionRoot.getRoot());
+ }
+
+ /**
+ * Stores the objectToStore
+ *
+ * @param objectToStore which is stored
+ * @return what EmbeddedStorageManager#store returns
+ */
+ public long store(final Object objectToStore)
+ {
+ return this.tunnelingManager.store(objectToStore);
+ }
+
+ /**
+ * Shuts down the datastore.
+ *
+ * @return what EmbeddedStorageManager#storeRoot shutdown
+ */
+ public boolean shutdown()
+ {
+ return this.tunnelingManager.shutdown();
+ }
+
+ /**
+ * Closes the datastore.
+ */
+ @Override
+ public void close()
+ {
+ this.tunnelingManager.close();
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/versionagnostic/VersionAgnosticMigrationManager.java b/micro-migration/src/main/java/software/xdev/micromigration/versionagnostic/VersionAgnosticMigrationManager.java
new file mode 100644
index 0000000..b655376
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/versionagnostic/VersionAgnosticMigrationManager.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.versionagnostic;
+
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import software.xdev.micromigration.migrater.MicroMigrater;
+import software.xdev.micromigration.notification.ScriptExecutionNotificationWithoutScriptReference;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.version.Versioned;
+import software.xdev.micromigration.version.VersionedAndKeeperOfHistory;
+
+
+/**
+ * Manages a given object and keeps the version for it.
+ *
+ * Can be used to keep the version of the Root-Object and therefor keep the whole datastore versioned.
+ *
+ *
+ * {@code VersionAgnostic} because it should be independent of the actual implementation used.
+ *
+ *
+ * @param The actually used EmbeddedStorageManager
+ */
+public class VersionAgnosticMigrationManager
+{
+ private final Supplier currentVersionGetter;
+ private final Consumer currentVersionSetter;
+ private final Consumer currentVersionStorer;
+ private final MicroMigrater migrater;
+ private final VersionAgnosticMigrationEmbeddedStorageManager, T> storageManager;
+
+ /**
+ * Much more complicated constructor than
+ * {@link VersionAgnosticMigrationManager#VersionAgnosticMigrationManager(Versioned, MicroMigrater,
+ * VersionAgnosticMigrationEmbeddedStorageManager)}
+ *
+ * @param currentVersionGetter which supplies the current version of the object to update.
+ * @param currentVersionSetter which sets the new version of the object in some membervariable. This Consumer is
+ * not
+ * supposed to store the version, but only save it in some membervariable to be stored
+ * after.
+ * @param currentVersionStorer which is supposed to store the new version of the object somewhere in the datastore.
+ * @param migrater does the actual migration with the given {@link VersionAgnosticMigrationScript}
+ * @param storageManager for the {@link VersionAgnosticMigrationScript}s to use. Is not used for the storing
+ * of the new version.
+ */
+ public VersionAgnosticMigrationManager(
+ final Supplier currentVersionGetter,
+ final Consumer currentVersionSetter,
+ final Consumer currentVersionStorer,
+ final MicroMigrater migrater,
+ final VersionAgnosticMigrationEmbeddedStorageManager, T> storageManager
+ )
+ {
+ Objects.requireNonNull(currentVersionGetter);
+ Objects.requireNonNull(currentVersionSetter);
+ Objects.requireNonNull(currentVersionStorer);
+ Objects.requireNonNull(migrater);
+ Objects.requireNonNull(storageManager);
+ this.currentVersionGetter = currentVersionGetter;
+ this.currentVersionSetter = currentVersionSetter;
+ this.currentVersionStorer = currentVersionStorer;
+ this.migrater = migrater;
+ this.storageManager = storageManager;
+ }
+
+ /**
+ * Simple Constructor.
+ *
+ * @param versionedObject which provides getter and setter for the current version. This object will be stored
+ * after
+ * the {@link VersionAgnosticMigrationScript}s are executed.
+ * @param migrater does the actual migration with the given {@link VersionAgnosticMigrationScript}
+ * @param storageManager for the {@link VersionAgnosticMigrationScript}s to use. Is not used for the storing of
+ * the
+ * new version.
+ */
+ public VersionAgnosticMigrationManager(
+ final Versioned versionedObject,
+ final MicroMigrater migrater,
+ final VersionAgnosticMigrationEmbeddedStorageManager, T> storageManager
+ )
+ {
+ this(
+ versionedObject::getVersion,
+ versionedObject::setVersion,
+ version -> storageManager.store(versionedObject),
+ migrater,
+ storageManager
+ );
+ Objects.requireNonNull(versionedObject);
+ }
+
+ /**
+ * Simple Constructor.
+ *
+ * @param versionedObject which provides getter and setter for the current version. This object will be stored
+ * after
+ * the {@link VersionAgnosticMigrationScript}s are executed.
+ * @param migrater does the actual migration with the given {@link VersionAgnosticMigrationScript}
+ * @param storageManager for the {@link VersionAgnosticMigrationScript}s to use. Is not used for the storing of
+ * the
+ * new version.
+ */
+ public VersionAgnosticMigrationManager(
+ final VersionedAndKeeperOfHistory versionedObject,
+ final MicroMigrater migrater,
+ final VersionAgnosticMigrationEmbeddedStorageManager, T> storageManager
+ )
+ {
+ this(
+ versionedObject::getVersion,
+ versionedObject::setVersion,
+ version -> storageManager.store(versionedObject),
+ migrater,
+ storageManager
+ );
+ Objects.requireNonNull(versionedObject);
+ migrater.registerNotificationConsumer(
+ executedScript ->
+ versionedObject.addExecutedScript(new ScriptExecutionNotificationWithoutScriptReference(executedScript))
+ );
+ }
+
+ /**
+ * Migrates the given object to the newest possible version, defined by the {@link MicroMigrater}.
+ *
+ * @param objectToMigrate is given to the {@link MicroMigrater} for migrating upon
+ */
+ public void migrate(final Object objectToMigrate)
+ {
+ final MigrationVersion versionBeforeUpdate = this.currentVersionGetter.get();
+ // Execute Updates
+ final MigrationVersion versionAfterUpdate = this.migrater.migrateToNewest(
+ versionBeforeUpdate,
+ this.storageManager,
+ objectToMigrate
+ );
+ // Update stored version, if needed
+ if(!versionAfterUpdate.equals(versionBeforeUpdate))
+ {
+ this.currentVersionSetter.accept(versionAfterUpdate);
+ this.currentVersionStorer.accept(versionAfterUpdate);
+ }
+ }
+}
diff --git a/micro-migration/src/main/java/software/xdev/micromigration/versionagnostic/VersionAgnosticTunnelingEmbeddedStorageManager.java b/micro-migration/src/main/java/software/xdev/micromigration/versionagnostic/VersionAgnosticTunnelingEmbeddedStorageManager.java
new file mode 100644
index 0000000..45e3c73
--- /dev/null
+++ b/micro-migration/src/main/java/software/xdev/micromigration/versionagnostic/VersionAgnosticTunnelingEmbeddedStorageManager.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.versionagnostic;
+
+/**
+ * Wrapper class for the {@link org.eclipse.store.storage.embedded.types.EmbeddedStorageManager} interface.
+ *
+ * It's simply an interface to not directly depend on the underlying framework, but still use its functionality.
+ *
+ *
+ * {@code VersionAgnostic} because it should be independent of the actual implementation used.
+ *
+ *
+ * @param Represents the actually used EmbeddedStorageManager
+ */
+public interface VersionAgnosticTunnelingEmbeddedStorageManager
+ extends AutoCloseable
+{
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ T start();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ Object root();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @param newRoot whatever the actual EmbeddedStorageManager uses this for
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ Object setRoot(Object newRoot);
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ long storeRoot();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ boolean shutdown();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ boolean isAcceptingTasks();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ boolean isRunning();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ boolean isStartingUp();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ boolean isShuttingDown();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ */
+ void checkAcceptingTasks();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ long initializationTime();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ long operationModeTime();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ boolean isActive();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @param nanoTimeBudget whatever the actual EmbeddedStorageManager uses this for
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ boolean issueGarbageCollection(long nanoTimeBudget);
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @param nanoTimeBudget whatever the actual EmbeddedStorageManager uses this for
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ boolean issueFileCheck(long nanoTimeBudget);
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ *
+ * @param instance whatever the actual EmbeddedStorageManager uses this for
+ * @return what the actual EmbeddedStorageManager returns
+ */
+ long store(Object instance);
+
+ /**
+ * @return the actual EmbeddedStorageManager
+ */
+ T getNativeStorageManager();
+
+ /**
+ * Simply relais the method-call to the EmbeddedStorageManager
+ */
+ @Override
+ void close();
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/IntroduceMigrationOnExistingDatastoreTest.java b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/IntroduceMigrationOnExistingDatastoreTest.java
new file mode 100644
index 0000000..7668cb9
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/IntroduceMigrationOnExistingDatastoreTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore.integration;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.nio.file.Path;
+
+import org.eclipse.store.storage.embedded.types.EmbeddedStorage;
+import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorage;
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.eclipsestore.util.MicroMigrationScriptDummy;
+import software.xdev.micromigration.migrater.ExplicitMigrater;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+class IntroduceMigrationOnExistingDatastoreTest
+{
+ static final String ROOT = "OriginalRoot";
+
+ @Test
+ void checkIntroducingMigrationOnExistingDatastoreMigrationEmbeddedStorageManager(@TempDir final Path storageFolder)
+ {
+ try(final EmbeddedStorageManager storageManager = EmbeddedStorage.start(storageFolder))
+ {
+ storageManager.setRoot(ROOT);
+ storageManager.storeRoot();
+ }
+
+ final ExplicitMigrater migrater = new ExplicitMigrater(
+ new MicroMigrationScriptDummy(new MigrationVersion(1))
+ );
+ try(final MigrationEmbeddedStorageManager migrationStorageManager = MigrationEmbeddedStorage.start(
+ storageFolder,
+ migrater))
+ {
+ assertEquals(ROOT, migrationStorageManager.root());
+ assertEquals(1, migrationStorageManager.getCurrentVersion().getVersions()[0]);
+ }
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/MigrationScriptAfterScriptTest.java b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/MigrationScriptAfterScriptTest.java
new file mode 100644
index 0000000..0f18f5c
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/MigrationScriptAfterScriptTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore.integration;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.serializer.persistence.types.Storer;
+import org.eclipse.store.storage.embedded.types.EmbeddedStorage;
+import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorage;
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.eclipsestore.MigrationManager;
+import software.xdev.micromigration.migrater.ExplicitMigrater;
+import software.xdev.micromigration.scripts.SimpleTypedMigrationScript;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.version.Versioned;
+import software.xdev.micromigration.version.VersionedObject;
+
+
+class MigrationScriptAfterScriptTest
+{
+ @Test
+ void checkMigrationWithThreeDifferentMigraterMigrationEmbeddedStorageManager(@TempDir final Path storageFolder)
+ {
+ // First run without any migration script
+ final ExplicitMigrater firstMigrater = new ExplicitMigrater();
+ try(final MigrationEmbeddedStorageManager migrationStorageManager = MigrationEmbeddedStorage.start(
+ storageFolder,
+ firstMigrater))
+ {
+ migrationStorageManager.setRoot(0);
+ migrationStorageManager.storeRoot();
+ assertEquals(0, migrationStorageManager.root());
+ Assertions.assertEquals(new MigrationVersion(0), migrationStorageManager.getCurrentVersion());
+ }
+
+ // Run with one migration script
+ final VersionAgnosticMigrationScript firstScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) -> context.getStorageManager().setRoot(1)
+ );
+ final ExplicitMigrater secondMigrater = new ExplicitMigrater(firstScript);
+ try(final MigrationEmbeddedStorageManager migrationStorageManager = MigrationEmbeddedStorage.start(
+ storageFolder,
+ secondMigrater))
+ {
+ assertEquals(1, migrationStorageManager.root());
+ Assertions.assertEquals(new MigrationVersion(1), migrationStorageManager.getCurrentVersion());
+ }
+
+ // Run with two migration scripts
+ final VersionAgnosticMigrationScript secondScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(2),
+ (context) -> context.getStorageManager().setRoot(2)
+ );
+ final ExplicitMigrater thirdMigrater = new ExplicitMigrater(firstScript, secondScript);
+ try(final MigrationEmbeddedStorageManager migrationStorageManager = MigrationEmbeddedStorage.start(
+ storageFolder,
+ thirdMigrater))
+ {
+ assertEquals(2, migrationStorageManager.root());
+ Assertions.assertEquals(new MigrationVersion(2), migrationStorageManager.getCurrentVersion());
+ }
+ }
+
+ @Test
+ void checkMigrationAndUseStorer(@TempDir final Path storageFolder)
+ {
+ final List firstList = new ArrayList<>();
+ // Run with one migration script
+ final VersionAgnosticMigrationScript firstScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) ->
+ {
+ context.getStorageManager().setRoot(firstList);
+ firstList.add("1");
+ final Storer storer = context.getStorageManager().getNativeStorageManager().createStorer();
+ storer.store(firstList);
+ storer.commit();
+ }
+ );
+
+ final ExplicitMigrater migrater = new ExplicitMigrater(firstScript);
+ try(final MigrationEmbeddedStorageManager migrationStorageManager = MigrationEmbeddedStorage.start(
+ storageFolder,
+ migrater))
+ {
+ assertEquals(1, ((List)migrationStorageManager.root()).size());
+ }
+ }
+
+ @Test
+ void checkMigrationWithScriptExecutionNotification(@TempDir final Path storageFolder)
+ {
+ final VersionAgnosticMigrationScript firstScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) -> context.getStorageManager().setRoot(1)
+ );
+ final ExplicitMigrater migrater = new ExplicitMigrater(firstScript);
+ final AtomicBoolean notificationReceived = new AtomicBoolean(false);
+ migrater.registerNotificationConsumer(
+ notification ->
+ {
+ Assertions.assertEquals(firstScript, notification.getExecutedScript());
+ Assertions.assertEquals(new MigrationVersion(0), notification.getSourceVersion());
+ Assertions.assertEquals(new MigrationVersion(1), notification.getTargetVersion());
+ notificationReceived.set(true);
+ }
+ );
+ try(final MigrationEmbeddedStorageManager ignored = MigrationEmbeddedStorage.start(storageFolder, migrater))
+ {
+ assertTrue(notificationReceived.get());
+ }
+ }
+
+ @Test
+ void checkMigrationWithThreeDifferentMigraterStandaloneMicroMigrationManager(@TempDir final Path storageFolder)
+ {
+ // First run without any migration script
+ try(final EmbeddedStorageManager storageManager = this.startEmbeddedStorageManagerWithPath(storageFolder))
+ {
+ final VersionedObject firstRoot = new VersionedObject<>(0);
+ storageManager.setRoot(firstRoot);
+ storageManager.storeRoot();
+ assertEquals(Integer.valueOf(0), firstRoot.getObject());
+ assertEquals(new MigrationVersion(0), firstRoot.getVersion());
+ }
+
+ // Run with one migration script
+ final VersionAgnosticMigrationScript, MigrationEmbeddedStorageManager> firstScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) -> context.getMigratingObject().setObject(1)
+ );
+ try(final EmbeddedStorageManager storageManager = this.startEmbeddedStorageManagerWithPath(storageFolder))
+ {
+ new MigrationManager(
+ (Versioned)storageManager.root(),
+ new ExplicitMigrater(firstScript),
+ storageManager
+ )
+ .migrate(storageManager.root());
+ @SuppressWarnings("unchecked")
+ final VersionedObject currentRoot = (VersionedObject)storageManager.root();
+ assertEquals(Integer.valueOf(1), currentRoot.getObject());
+ assertEquals(new MigrationVersion(1), currentRoot.getVersion());
+ }
+
+ // Run with two migration scripts
+ final VersionAgnosticMigrationScript, MigrationEmbeddedStorageManager> secondScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(2),
+ (context) -> context.getMigratingObject().setObject(2)
+ );
+ try(final EmbeddedStorageManager storageManager = this.startEmbeddedStorageManagerWithPath(storageFolder))
+ {
+ new MigrationManager(
+ (Versioned)storageManager.root(),
+ new ExplicitMigrater(firstScript, secondScript),
+ storageManager
+ )
+ .migrate(storageManager.root());
+ @SuppressWarnings("unchecked")
+ final VersionedObject currentRoot = (VersionedObject)storageManager.root();
+ assertEquals(Integer.valueOf(2), currentRoot.getObject());
+ assertEquals(new MigrationVersion(2), currentRoot.getVersion());
+ }
+ }
+
+ private EmbeddedStorageManager startEmbeddedStorageManagerWithPath(final Path storageFolder)
+ {
+ return EmbeddedStorage.start(storageFolder);
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/MultipleScriptsTest.java b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/MultipleScriptsTest.java
new file mode 100644
index 0000000..458e1fd
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/MultipleScriptsTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore.integration;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorage;
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.migrater.ExplicitMigrater;
+import software.xdev.micromigration.migrater.VersionAlreadyRegisteredException;
+import software.xdev.micromigration.scripts.SimpleTypedMigrationScript;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+class MultipleScriptsTest
+{
+ @Test
+ void checkMigrationWithTwoScriptsAtOnceMigrationEmbeddedStorageManager(@TempDir final Path storageFolder)
+ {
+ final VersionAgnosticMigrationScript firstScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) -> context.getStorageManager().setRoot(1)
+ );
+ final VersionAgnosticMigrationScript secondScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(2),
+ (context) -> context.getStorageManager().setRoot(2)
+ );
+ final ExplicitMigrater migrater = new ExplicitMigrater(firstScript, secondScript);
+ try(final MigrationEmbeddedStorageManager migrationStorageManager = MigrationEmbeddedStorage.start(
+ storageFolder,
+ migrater))
+ {
+ assertEquals(2, migrationStorageManager.root());
+ assertEquals(new MigrationVersion(2), migrationStorageManager.getCurrentVersion());
+ }
+ }
+
+ @Test
+ void checkMigrationWithTwoScriptsWithSameVersion()
+ {
+ final VersionAgnosticMigrationScript firstScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) -> context.getStorageManager().setRoot(1)
+ );
+ final VersionAgnosticMigrationScript secondScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) -> context.getStorageManager().setRoot(2)
+ );
+ Assertions.assertThrows(VersionAlreadyRegisteredException.class, () ->
+ new ExplicitMigrater(firstScript, secondScript)
+ );
+ }
+
+ @Test
+ void checkMigrationWithThreeScriptsWithSameVersion()
+ {
+ final VersionAgnosticMigrationScript firstScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) -> context.getStorageManager().setRoot(1)
+ );
+ final VersionAgnosticMigrationScript secondScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(2),
+ (context) -> context.getStorageManager().setRoot(2)
+ );
+ final VersionAgnosticMigrationScript thirdScript =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) -> context.getStorageManager().setRoot(3)
+ );
+ Assertions.assertThrows(VersionAlreadyRegisteredException.class, () ->
+ new ExplicitMigrater(firstScript, secondScript, thirdScript)
+ );
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/StoreStuffInMigrationStorageManagerTest.java b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/StoreStuffInMigrationStorageManagerTest.java
new file mode 100644
index 0000000..19fa22c
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/integration/StoreStuffInMigrationStorageManagerTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore.integration;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorage;
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.migrater.ExplicitMigrater;
+import software.xdev.micromigration.scripts.SimpleTypedMigrationScript;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+class StoreStuffInMigrationStorageManagerTest
+{
+ static class RootClass
+ {
+ private final ChildClass child = new ChildClass();
+ }
+
+
+ static class ChildClass
+ {
+ private int i;
+ }
+
+ @Test
+ void checkStoringSomethingAfterUpdating(@TempDir final Path storageFolder)
+ {
+ final VersionAgnosticMigrationScript script =
+ new SimpleTypedMigrationScript<>(
+ new MigrationVersion(1),
+ (context) -> {
+ }
+ );
+ final ExplicitMigrater migrater = new ExplicitMigrater(script);
+ // Create new store and change stored object
+ try(final MigrationEmbeddedStorageManager migrationStorageManager = MigrationEmbeddedStorage.start(
+ storageFolder,
+ migrater))
+ {
+ migrationStorageManager.setRoot(new RootClass());
+ migrationStorageManager.storeRoot();
+ final RootClass storedRoot = ((RootClass)migrationStorageManager.root());
+ assertEquals(0, storedRoot.child.i);
+ ((RootClass)migrationStorageManager.root()).child.i = 1;
+ migrationStorageManager.store(storedRoot.child);
+ assertEquals(1, storedRoot.child.i);
+ }
+ // Check if stored object is correct
+ try(final MigrationEmbeddedStorageManager migrationStorageManager = MigrationEmbeddedStorage.start(
+ storageFolder,
+ migrater))
+ {
+ final RootClass storedRoot = ((RootClass)migrationStorageManager.root());
+ assertNotNull(storedRoot);
+ assertEquals(1, storedRoot.child.i);
+ }
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/migrater/ExplicitMigraterTest.java b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/migrater/ExplicitMigraterTest.java
new file mode 100644
index 0000000..3db6830
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/migrater/ExplicitMigraterTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore.migrater;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorage;
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.eclipsestore.util.MicroMigrationScriptDummy;
+import software.xdev.micromigration.migrater.ExplicitMigrater;
+import software.xdev.micromigration.scripts.SimpleTypedMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+class ExplicitMigraterTest
+{
+
+ @Test
+ void checkGetSortedScriptsEmpty()
+ {
+ final ExplicitMigrater migrater = new ExplicitMigrater();
+ assertEquals(0, migrater.getSortedScripts().size());
+ }
+
+ @Test
+ void checkGetSortedScriptsSorted()
+ {
+ final ExplicitMigrater migrater = new ExplicitMigrater(
+ new MicroMigrationScriptDummy(new MigrationVersion(1)),
+ new MicroMigrationScriptDummy(new MigrationVersion(2))
+ );
+ assertEquals(1, migrater.getSortedScripts().first().getTargetVersion().getVersions()[0]);
+ assertEquals(2, migrater.getSortedScripts().last().getTargetVersion().getVersions()[0]);
+ }
+
+ @Test
+ void checkGetSortedScriptsUnsorted()
+ {
+ final ExplicitMigrater migrater = new ExplicitMigrater(
+ new MicroMigrationScriptDummy(new MigrationVersion(2)),
+ new MicroMigrationScriptDummy(new MigrationVersion(1))
+ );
+ assertEquals(1, migrater.getSortedScripts().first().getTargetVersion().getVersions()[0]);
+ assertEquals(2, migrater.getSortedScripts().last().getTargetVersion().getVersions()[0]);
+ }
+
+ @Test
+ void checkWrongTypedVersionedScript(@TempDir final Path storageFolder)
+ {
+ try(final MigrationEmbeddedStorageManager storageManager = MigrationEmbeddedStorage.start(
+ storageFolder,
+ new ExplicitMigrater()))
+ {
+ storageManager.setRoot("SomeString");
+ storageManager.storeRoot();
+ }
+ final ExplicitMigrater migrater = new ExplicitMigrater(
+ new SimpleTypedMigrationScript(
+ new MigrationVersion(1),
+ (context) -> context.getStorageManager().setRoot(context.getMigratingObject() + 1)
+ )
+ );
+ Assertions.assertThrows(
+ ClassCastException.class,
+ () -> MigrationEmbeddedStorage.start(storageFolder, migrater));
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/util/MicroMigrationScriptDummy.java b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/util/MicroMigrationScriptDummy.java
new file mode 100644
index 0000000..2b913c6
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/eclipsestore/util/MicroMigrationScriptDummy.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.eclipsestore.util;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+public class MicroMigrationScriptDummy
+ implements VersionAgnosticMigrationScript
+{
+ private final MigrationVersion version;
+
+ public MicroMigrationScriptDummy(final MigrationVersion version)
+ {
+ this.version = version;
+ }
+
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return this.version;
+ }
+
+ @Override
+ public void migrate(final Context context)
+ {
+ // Don't do anything.
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/ReflectiveMigraterTest.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/ReflectiveMigraterTest.java
new file mode 100644
index 0000000..88ac538
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/ReflectiveMigraterTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import software.xdev.micromigration.migrater.reflection.scripts.abstractReflectiveSuperClass.v1_ValidScript;
+
+
+class ReflectiveMigraterTest
+{
+ @Test
+ void testValidScript()
+ {
+ final ReflectiveMigrater migrater =
+ new ReflectiveMigrater("software.xdev.micromigration.migrater.reflection.scripts.valid");
+ assertEquals(1, migrater.getSortedScripts().size());
+ assertEquals(
+ software.xdev.micromigration.migrater.reflection.scripts.valid.ValidScript.class,
+ migrater.getSortedScripts().first().getClass()
+ );
+ }
+
+ @Test
+ void testValidScriptWithIrrelevantClasses()
+ {
+ final ReflectiveMigrater migrater =
+ new ReflectiveMigrater("software.xdev.micromigration.migrater.reflection.scripts"
+ + ".moreClassesIncludingValid");
+ assertEquals(1, migrater.getSortedScripts().size());
+ assertEquals(
+ software.xdev.micromigration.migrater.reflection.scripts.moreClassesIncludingValid.ValidScript.class,
+ migrater.getSortedScripts().first().getClass()
+ );
+ }
+
+ @Test
+ void testValidScriptWithSubpackages()
+ {
+ final ReflectiveMigrater migrater =
+ new ReflectiveMigrater("software.xdev.micromigration.migrater.reflection.scripts.includeSubPackages");
+ assertEquals(2, migrater.getSortedScripts().size());
+ assertEquals(
+ software.xdev.micromigration.migrater.reflection.scripts.includeSubPackages.ValidScript.class,
+ migrater.getSortedScripts().first().getClass()
+ );
+ assertEquals(
+ software.xdev.micromigration.migrater.reflection.scripts.includeSubPackages.subpackage
+ .ValidScriptInSubpackage.class,
+ migrater.getSortedScripts().last().getClass()
+ );
+ }
+
+ @Test
+ void testPackageWithNoScript()
+ {
+ final ReflectiveMigrater migrater =
+ new ReflectiveMigrater("software.xdev.micromigration.migrater.reflection.scripts.packageNotExisting");
+ assertEquals(0, migrater.getSortedScripts().size());
+ }
+
+ @Test
+ void testExceptionThrowingScript()
+ {
+ Assertions.assertThrows(ScriptInstantiationException.class, () -> {
+ new ReflectiveMigrater("software.xdev.micromigration.migrater.reflection.scripts.exceptionThrowing");
+ });
+ }
+
+ @Test
+ void testErrorThrowingScript()
+ {
+ Assertions.assertThrows(ScriptInstantiationException.class, () -> {
+ new ReflectiveMigrater("software.xdev.micromigration.migrater.reflection.scripts.errorThrowing");
+ });
+ }
+
+ @Test
+ void testNoCorrectConstructor()
+ {
+ Assertions.assertThrows(ScriptInstantiationException.class, () -> {
+ new ReflectiveMigrater("software.xdev.micromigration.migrater.reflection.scripts.noCorrectConstructor");
+ });
+ }
+
+ @Test
+ void testAbstractSuperClass()
+ {
+ final ReflectiveMigrater migrater =
+ new ReflectiveMigrater("software.xdev.micromigration.migrater.reflection.scripts.abstractSuperClass");
+ assertEquals(1, migrater.getSortedScripts().size());
+ assertEquals(
+ software.xdev.micromigration.migrater.reflection.scripts.abstractSuperClass.ValidScript.class,
+ migrater.getSortedScripts().first().getClass()
+ );
+ }
+
+ @Test
+ void testReflectiveVersion()
+ {
+ final ReflectiveMigrater migrater =
+ new ReflectiveMigrater("software.xdev.micromigration.migrater.reflection.scripts.reflectiveVersion");
+ assertEquals(1, migrater.getSortedScripts().size());
+ assertEquals(
+ software.xdev.micromigration.migrater.reflection.scripts.reflectiveVersion.v1_ValidScript.class,
+ migrater.getSortedScripts().first().getClass()
+ );
+ }
+
+ @Test
+ void testReflectiveSuperClass()
+ {
+ final ReflectiveMigrater migrater =
+ new ReflectiveMigrater(
+ "software.xdev.micromigration.migrater.reflection.scripts.abstractReflectiveSuperClass");
+ assertEquals(1, migrater.getSortedScripts().size());
+ assertEquals(
+ v1_ValidScript.class,
+ migrater.getSortedScripts().first().getClass()
+ );
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractReflectiveSuperClass/AbstractScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractReflectiveSuperClass/AbstractScript.java
new file mode 100644
index 0000000..f7b1b4c
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractReflectiveSuperClass/AbstractScript.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.abstractReflectiveSuperClass;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.ReflectiveVersionMigrationScript;
+
+
+public abstract class AbstractScript extends ReflectiveVersionMigrationScript
+{
+
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractReflectiveSuperClass/v1_ValidScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractReflectiveSuperClass/v1_ValidScript.java
new file mode 100644
index 0000000..a9b2dda
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractReflectiveSuperClass/v1_ValidScript.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.abstractReflectiveSuperClass;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+
+
+@SuppressWarnings("checkstyle:TypeName")
+public class v1_ValidScript extends AbstractScript
+{
+ @Override
+ public void migrate(final Context context)
+ {
+ // Do nothing
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractSuperClass/AbstractScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractSuperClass/AbstractScript.java
new file mode 100644
index 0000000..92d310b
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractSuperClass/AbstractScript.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.abstractSuperClass;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+public abstract class AbstractScript implements VersionAgnosticMigrationScript
+{
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return new MigrationVersion(1);
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractSuperClass/ValidScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractSuperClass/ValidScript.java
new file mode 100644
index 0000000..55ae044
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/abstractSuperClass/ValidScript.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.abstractSuperClass;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+
+
+public class ValidScript extends AbstractScript
+{
+ @Override
+ public void migrate(final Context context)
+ {
+ // Do nothing
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/errorThrowing/ErrorThrowingScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/errorThrowing/ErrorThrowingScript.java
new file mode 100644
index 0000000..e0de160
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/errorThrowing/ErrorThrowingScript.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.errorThrowing;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+public class ErrorThrowingScript implements VersionAgnosticMigrationScript
+{
+ public ErrorThrowingScript()
+ {
+ throw new Error();
+ }
+
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return new MigrationVersion(1);
+ }
+
+ @Override
+ public void migrate(final Context context)
+ {
+ // Do nothing
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/exceptionThrowing/ExceptionThrowingScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/exceptionThrowing/ExceptionThrowingScript.java
new file mode 100644
index 0000000..1b3bb1e
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/exceptionThrowing/ExceptionThrowingScript.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.exceptionThrowing;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+public class ExceptionThrowingScript implements VersionAgnosticMigrationScript
+{
+ public ExceptionThrowingScript() throws Exception
+ {
+ throw new Exception();
+ }
+
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return new MigrationVersion(1);
+ }
+
+ @Override
+ public void migrate(final Context context)
+ {
+ // Do nothing
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/includeSubPackages/ValidScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/includeSubPackages/ValidScript.java
new file mode 100644
index 0000000..e11bfd8
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/includeSubPackages/ValidScript.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.includeSubPackages;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+public class ValidScript implements VersionAgnosticMigrationScript
+{
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return new MigrationVersion(1);
+ }
+
+ @Override
+ public void migrate(final Context context)
+ {
+ // Do nothing
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/includeSubPackages/subpackage/ValidScriptInSubpackage.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/includeSubPackages/subpackage/ValidScriptInSubpackage.java
new file mode 100644
index 0000000..336101d
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/includeSubPackages/subpackage/ValidScriptInSubpackage.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.includeSubPackages.subpackage;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+public class ValidScriptInSubpackage implements VersionAgnosticMigrationScript
+{
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return new MigrationVersion(2);
+ }
+
+ @Override
+ public void migrate(final Context context)
+ {
+ // Do nothing
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/moreClassesIncludingValid/IrrelevantClass.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/moreClassesIncludingValid/IrrelevantClass.java
new file mode 100644
index 0000000..6b45813
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/moreClassesIncludingValid/IrrelevantClass.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.moreClassesIncludingValid;
+
+public class IrrelevantClass
+{
+
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/moreClassesIncludingValid/ValidScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/moreClassesIncludingValid/ValidScript.java
new file mode 100644
index 0000000..c67b8b6
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/moreClassesIncludingValid/ValidScript.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.moreClassesIncludingValid;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+public class ValidScript implements VersionAgnosticMigrationScript
+{
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return new MigrationVersion(1);
+ }
+
+ @Override
+ public void migrate(final Context context)
+ {
+ // Do nothing
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/noCorrectConstructor/NoCorrectConstructorScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/noCorrectConstructor/NoCorrectConstructorScript.java
new file mode 100644
index 0000000..a94408a
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/noCorrectConstructor/NoCorrectConstructorScript.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.noCorrectConstructor;
+
+import java.util.logging.Logger;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+public class NoCorrectConstructorScript
+ implements VersionAgnosticMigrationScript
+{
+ private final String argument;
+
+ public NoCorrectConstructorScript(final String argument)
+ {
+ this.argument = argument;
+ }
+
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return new MigrationVersion(1);
+ }
+
+ @Override
+ public void migrate(final Context context)
+ {
+ Logger.getGlobal().info(this.argument);
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/reflectiveVersion/v1_ValidScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/reflectiveVersion/v1_ValidScript.java
new file mode 100644
index 0000000..8655a3d
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/reflectiveVersion/v1_ValidScript.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.reflectiveVersion;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.ReflectiveVersionMigrationScript;
+
+
+@SuppressWarnings("checkstyle:TypeName")
+public class v1_ValidScript extends ReflectiveVersionMigrationScript
+{
+ @Override
+ public void migrate(final Context context)
+ {
+ // Do nothing
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/valid/ValidScript.java b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/valid/ValidScript.java
new file mode 100644
index 0000000..3d1bb0a
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/migrater/reflection/scripts/valid/ValidScript.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.migrater.reflection.scripts.valid;
+
+import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager;
+import software.xdev.micromigration.scripts.Context;
+import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript;
+import software.xdev.micromigration.version.MigrationVersion;
+
+
+public class ValidScript implements VersionAgnosticMigrationScript
+{
+ @Override
+ public MigrationVersion getTargetVersion()
+ {
+ return new MigrationVersion(1);
+ }
+
+ @Override
+ public void migrate(final Context context)
+ {
+ // Do nothing
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/scripts/ReflectiveVersionMigrationScriptTest.java b/micro-migration/src/test/java/software/xdev/micromigration/scripts/ReflectiveVersionMigrationScriptTest.java
new file mode 100644
index 0000000..de0b5b2
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/scripts/ReflectiveVersionMigrationScriptTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.scripts;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import software.xdev.micromigration.version.MigrationVersion;
+import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager;
+
+
+@SuppressWarnings({"checkstyle:TypeName", "checkstyle:MethodName"})
+class ReflectiveVersionMigrationScriptTest
+{
+ public static class v1_CorrectClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void correctName_v1_CorrectClassName()
+ {
+ Assertions.assertEquals(new MigrationVersion(1), new v1_CorrectClassName().getTargetVersion());
+ }
+
+ public static class v1_1_CorrectClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void correctName_v1_1_CorrectClassName()
+ {
+ Assertions.assertEquals(new MigrationVersion(1, 1), new v1_1_CorrectClassName().getTargetVersion());
+ }
+
+ public static class v1_1_1_CorrectClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void correctName_v1_1_1_CorrectClassName()
+ {
+ Assertions.assertEquals(new MigrationVersion(1, 1, 1), new v1_1_1_CorrectClassName().getTargetVersion());
+ }
+
+ public static class v10_1_1_CorrectClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void correctName_v10_1_1_CorrectClassName()
+ {
+ Assertions.assertEquals(new MigrationVersion(10, 1, 1), new v10_1_1_CorrectClassName().getTargetVersion());
+ }
+
+ public static class v10_10_1_CorrectClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void correctName_v10_10_1_CorrectClassName()
+ {
+ Assertions.assertEquals(new MigrationVersion(10, 10, 1), new v10_10_1_CorrectClassName().getTargetVersion());
+ }
+
+ public static class v10_10_10_CorrectClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void correctName_v10_10_10_CorrectClassName()
+ {
+ Assertions.assertEquals(new MigrationVersion(10, 10, 10), new v10_10_10_CorrectClassName().getTargetVersion());
+ }
+
+ public static class a1_InvalidClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void invalidName_a1_InvalidClassName()
+ {
+ Assertions.assertThrows(IllegalArgumentException.class, a1_InvalidClassName::new);
+ }
+
+ public static class foo1_InvalidClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void invalidName_foo1_InvalidClassName()
+ {
+ Assertions.assertThrows(IllegalArgumentException.class, foo1_InvalidClassName::new);
+ }
+
+ public static class InvalidClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void invalidName_InvalidClassName()
+ {
+ Assertions.assertThrows(IllegalArgumentException.class, InvalidClassName::new);
+ }
+
+ public static class InvalidClassName_v1 extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void invalidName_InvalidClassName_v1()
+ {
+ Assertions.assertThrows(IllegalArgumentException.class, InvalidClassName_v1::new);
+ }
+
+ public static class v1_k_InvalidClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void invalidName_v1_k_InvalidClassName()
+ {
+ Assertions.assertThrows(IllegalArgumentException.class, v1_k_InvalidClassName::new);
+ }
+
+ public static class v1_k_2_InvalidClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void invalidName_v1_k_2_InvalidClassName()
+ {
+ Assertions.assertThrows(IllegalArgumentException.class, v1_k_2_InvalidClassName::new);
+ }
+
+ public static class v2147483648_InvalidClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void invalidName_v2147483648_InvalidClassName()
+ {
+ Assertions.assertThrows(IllegalArgumentException.class, v2147483648_InvalidClassName::new);
+ }
+
+ public static class v___InvalidClassName extends ReflectiveVersionMigrationScriptDummy
+ {
+ }
+
+ @Test
+ void invalidName_v___InvalidClassName()
+ {
+ Assertions.assertThrows(IllegalArgumentException.class, v___InvalidClassName::new);
+ }
+
+ public static class ReflectiveVersionMigrationScriptDummy
+ extends ReflectiveVersionMigrationScript>
+ {
+ @Override
+ public void migrate(
+ final Context> context)
+ {
+ // Dummy
+ }
+ }
+}
diff --git a/micro-migration/src/test/java/software/xdev/micromigration/version/MigrationVersionTest.java b/micro-migration/src/test/java/software/xdev/micromigration/version/MigrationVersionTest.java
new file mode 100644
index 0000000..359e117
--- /dev/null
+++ b/micro-migration/src/test/java/software/xdev/micromigration/version/MigrationVersionTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2021 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.micromigration.version;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+
+class MigrationVersionTest
+{
+ @Test
+ void checkToStringv1()
+ {
+ final MigrationVersion version = new MigrationVersion(1);
+ assertEquals("v1", version.toString());
+ }
+
+ @Test
+ void checkToStringv11()
+ {
+ final MigrationVersion version = new MigrationVersion(1, 1);
+ assertEquals("v1.1", version.toString());
+ }
+
+ @Test
+ void checkToStringv111()
+ {
+ final MigrationVersion version = new MigrationVersion(1, 1, 1);
+ assertEquals("v1.1.1", version.toString());
+ }
+
+ @Test
+ void checkToStringv0()
+ {
+ final MigrationVersion version = new MigrationVersion(0);
+ assertEquals("v0", version.toString());
+ }
+
+ @Test
+ void checkToStringvNull()
+ {
+ final MigrationVersion version = new MigrationVersion();
+ assertEquals("v0", version.toString());
+ }
+}
diff --git a/pom.xml b/pom.xml
index d15d6dc..ea264ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,8 +5,8 @@
4.0.0
software.xdev
- template-placeholder-root
- 1.0.0-SNAPSHOT
+ micro-migration-root
+ 2.0.1-SNAPSHOT
pom
@@ -15,8 +15,8 @@
- template-placeholder
- template-placeholder-demo
+ micro-migration
+ micro-migration-demo
diff --git a/renovate.json5 b/renovate.json5
index 2874d45..ce1352c 100644
--- a/renovate.json5
+++ b/renovate.json5
@@ -2,9 +2,19 @@
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"rebaseWhen": "behind-base-branch",
"packageRules": [
+ {
+ "description": "Group Eclipse Store",
+ "matchPackagePatterns": [
+ "^org.eclipse.store"
+ ],
+ "datasources": [
+ "maven"
+ ],
+ "groupName": "org.eclipse.store"
+ },
{
"description": "Ignore project internal dependencies",
- "packagePattern": "^software.xdev:template-placeholder",
+ "packagePattern": "^software.xdev:micro-migration",
"datasources": [
"maven"
],