blob: b0e0a5d42011c6b3debe3b3fb805966096beb0df [file] [log] [blame]
/**
********************************************************************************
* Copyright (c) 2015-2021 Robert Bosch GmbH and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Robert Bosch GmbH - initial API and implementation
********************************************************************************
*/
package org.eclipse.app4mc.amalthea.converters.ui.jobs;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.app4mc.amalthea.converters.common.MigrationException;
import org.eclipse.app4mc.amalthea.converters.common.MigrationHelper;
import org.eclipse.app4mc.amalthea.converters.common.MigrationInputFile;
import org.eclipse.app4mc.amalthea.converters.common.MigrationProcessor;
import org.eclipse.app4mc.amalthea.converters.common.MigrationSettings;
import org.eclipse.app4mc.amalthea.converters.common.MigrationStatusCode;
import org.eclipse.app4mc.amalthea.converters.common.utils.ModelVersion;
import org.eclipse.app4mc.amalthea.converters.ui.dialog.MigrationResultDialog;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.widgets.Display;
public class ModelMigrationJob extends Job {
private final MigrationProcessor migrationProcessor;
private final ArrayList<MigrationSettings> migrationSettings = new ArrayList<>();
private IProject project;
public ModelMigrationJob(String name, MigrationProcessor migrationProcessor, MigrationSettings migrationSettings, IProject project) {
super(name);
this.migrationProcessor = migrationProcessor;
this.project = project;
Map<String, Map<String, List<MigrationInputFile>>> collect = migrationSettings.getMigModelFiles().stream()
.collect(Collectors.groupingBy(
mig -> mig.getOriginalFile().getParent(),
Collectors.groupingBy(MigrationInputFile::getModelVersion)));
for (Map.Entry<String, Map<String, List<MigrationInputFile>>> folderMapping : collect.entrySet()) {
for (Map.Entry<String, List<MigrationInputFile>> versionMapping : folderMapping.getValue().entrySet()) {
MigrationSettings settings = new MigrationSettings();
settings.setInputModelVersion(versionMapping.getKey());
settings.setMigrationModelVersion(migrationSettings.getMigrationModelVersion());
settings.setProject(migrationSettings.getProject());
settings.setOutputDirectoryLocation(versionMapping.getValue().get(0).getOriginalFile().getParent());
settings.setCreateBackupFile(migrationSettings.isCreateBackupFile());
settings.getMigModelFiles().addAll(versionMapping.getValue());
this.migrationSettings.add(settings);
}
}
}
@Override
protected IStatus run(final IProgressMonitor monitor) {
boolean cancelled = false;
LinkedHashMap<String, String> results = new LinkedHashMap<>();
try {
for (MigrationSettings settings : this.migrationSettings) {
String ident = settings.getProject().toURI().relativize(settings.getMigModelFiles().get(0).getOriginalFile().getParentFile().toURI()).getPath();
if (cancelled) {
results.put(
ident,
"Migration cancelled.");
continue;
}
boolean inputValid = true;
try {
inputValid = MigrationHelper.isInputModelVersionValid(settings);
} catch (MigrationException e) {
results.put(
ident,
"Error during migration: " + e.getLocalizedMessage());
continue;
}
if (!inputValid) {
results.put(
ident,
"Model migration stopped as selected model files belong to different versions.");
continue;
} else {
if (settings.getInputModelVersion() != null
&& settings.getInputModelVersion().equals(settings.getMigrationModelVersion())) {
results.put(
ident,
"Selected models are compatible to latest AMALTHEA meta-model version ("
+ settings.getMigrationModelVersion()
+ "). It is not required to migrate these models !!");
continue;
} else if (!ModelVersion.isValidVersion(settings.getMigrationModelVersion())) {
results.put(
ident,
"The AMALTHEA meta-model version ("
+ settings.getMigrationModelVersion()
+ ") is not supported by the migration component !!");
continue;
} else if (settings.getInputModelVersion() != null
&& settings.getMigrationModelVersion() != null
&& ModelVersion.getModelVersion(settings.getInputModelVersion()).ordinal()
> ModelVersion.getModelVersion(settings.getMigrationModelVersion()).ordinal()) {
results.put(
ident,
"The target model version ("
+ settings.getMigrationModelVersion()
+ ") is older than the input model version ("
+ settings.getInputModelVersion() + "). "
+ "A backwards migration is not supported !!");
continue;
} else {
// Rename or copy the original files to filename_currentversion.amxmi
boolean backupSucceeded = true;
if (settings.isCreateBackupFile()) {
for (MigrationInputFile input : settings.getMigModelFiles()) {
backupSucceeded = MigrationHelper.createBackupFile(input);
}
}
if (backupSucceeded) {
try {
int result = migrationProcessor.execute(settings, monitor);
switch (result) {
case MigrationStatusCode.UNSUPPORTED_MODEL_VERSIONS:
results.put(
ident,
"Migration not supported for the selected model versions. Input Model version : \""
+ settings.getInputModelVersion()
+ "\" Output Model Version : \""
+ settings.getMigrationModelVersion() + "\"");
continue;
case MigrationStatusCode.CANCEL:
results.put(
ident,
"Migration cancelled.");
cancelled = true;
continue;
case MigrationStatusCode.ERROR:
results.put(
ident,
"Error during migration !!");
continue;
case MigrationStatusCode.OK:
results.put(
ident,
"Model Migration successful !!");
continue;
}
} catch (MigrationException e) {
results.put(
ident,
"Error during migration: " + e.getLocalizedMessage());
continue;
}
} else {
// do nothing as we could not backup source and this can data loss to user if he
// does not intend to loose his original model file
results.put(
ident,
"Migration Stopped : Source files could not be backed up before migration in "
+ settings.getMigModelFiles().get(0).getProjectRelativePath());
continue;
}
}
}
}
} finally {
this.migrationSettings.forEach(MigrationSettings::close);
}
Display.getDefault().asyncExec(() -> {
MigrationResultDialog dialog = new MigrationResultDialog(Display.getDefault().getActiveShell(), results);
dialog.open();
if (this.project != null) {
try {
this.project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
} catch (final CoreException e) {
Platform.getLog(getClass()).error(e.getLocalizedMessage(), e);
}
}
});
return Status.OK_STATUS;
}
@Override
public boolean belongsTo(final Object family) {
if (family != null && family.equals(IMigrationJobConstants.FAMILY)) {
return true;
}
return super.belongsTo(family);
}
}