diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index c51b6b8267..3764ea6bf8 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -93,6 +93,8 @@ image:doc/screenshots/inside_outside_labels.png[Isinde outside label example, 70
- https://github.com/eclipse-sirius/sirius-web/issues/3371[#3371] [diagram] Add new predicates in `NodeDescription` to specify whether a node is hidden/faded/normal by default.
- https://github.com/eclipse-sirius/sirius-web/issues/3372[#3372] [diagram] Add services in `DiagramServices` to hide, reveal, fade, and unfade nodes from AQL expressions and Java services.
- https://github.com/eclipse-sirius/sirius-web/issues/2839[#2839] [gantt] Add support for persisting task expand/collapse state
+- https://github.com/eclipse-sirius/sirius-web/issues/3333[#3333] [emf] Add support for the migration of semantic data
+
=== Improvements
@@ -114,6 +116,7 @@ They still support returning an `java.time.Instant` object directly.
- https://github.com/eclipse-sirius/sirius-web/issues/3377[#3377] [diagram] Only synchronize selection with explorer at the end of the process
- https://github.com/eclipse-sirius/sirius-web/issues/3359[#3359] Add report on document upload
- https://github.com/eclipse-sirius/sirius-web/issues/3405[#3405] [diagram] Display layout tools vertically in group palette
+- https://github.com/eclipse-sirius/sirius-web/issues/3333[#3333] [emf] Store the last migration performed in a document
== v2024.3.0
diff --git a/packages/emf/backend/sirius-components-emf/pom.xml b/packages/emf/backend/sirius-components-emf/pom.xml
index 86f99860eb..a2eb61ca88 100644
--- a/packages/emf/backend/sirius-components-emf/pom.xml
+++ b/packages/emf/backend/sirius-components-emf/pom.xml
@@ -102,7 +102,7 @@
org.eclipse.sirius.emfjson
org.eclipse.sirius.emfjson
- 2.3.7-SNAPSHOT
+ 2.3.8-SNAPSHOT
org.springframework.boot
diff --git a/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/ResourceMetadataAdapter.java b/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/ResourceMetadataAdapter.java
index 37f7cc21a4..a08fb45f57 100644
--- a/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/ResourceMetadataAdapter.java
+++ b/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/ResourceMetadataAdapter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2019, 2023 Obeo.
+ * Copyright (c) 2019, 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
@@ -17,6 +17,7 @@
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.sirius.components.emf.migration.api.MigrationData;
/**
* An EMF adapter used to store some metadata related to EMF Resources.
@@ -33,6 +34,8 @@
public class ResourceMetadataAdapter implements Adapter {
private String name;
+ private MigrationData migrationData;
+
private Notifier notifier;
public ResourceMetadataAdapter(String name) {
@@ -47,6 +50,14 @@ public void setName(String name) {
this.name = name;
}
+ public MigrationData getMigrationData() {
+ return migrationData;
+ }
+
+ public void setMigrationData(MigrationData migrationData) {
+ this.migrationData = migrationData;
+ }
+
@Override
public void notifyChanged(Notification notification) {
// do nothing
diff --git a/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/migration/MigrationService.java b/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/migration/MigrationService.java
new file mode 100644
index 0000000000..4f1bf95b9c
--- /dev/null
+++ b/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/migration/MigrationService.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.components.emf.migration;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
+import org.eclipse.sirius.components.emf.migration.api.IMigrationParticipant;
+import org.eclipse.sirius.components.emf.migration.api.MigrationData;
+import org.eclipse.sirius.components.emf.ResourceMetadataAdapter;
+import org.eclipse.sirius.emfjson.resource.JsonResource;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+
+/**
+ * Specialized BasicExtendedMetaData.
+ *
+ * @author mcharfadi
+ */
+public class MigrationService extends BasicExtendedMetaData implements JsonResource.IJsonResourceProcessor {
+ private MigrationData documentMigrationData;
+
+ private final List migrationParticipants;
+
+ public MigrationService(List migrationParticipants) {
+ this.migrationParticipants = Objects.requireNonNull(migrationParticipants);
+ this.documentMigrationData = new MigrationData("none", "0");
+ }
+
+ private boolean isCandidateVersion(IMigrationParticipant migrationParticipant) {
+ return migrationParticipant.getVersion().compareTo(this.documentMigrationData.migrationVersion()) > 0;
+ }
+
+ @Override
+ public EStructuralFeature getElement(EClass eClass, String namespace, String eStructuralFeatureName) {
+ EStructuralFeature structuralFeature = eClass.getEStructuralFeature(eStructuralFeatureName);
+ var migrationParticipantsCandidate = migrationParticipants.stream()
+ .filter(this::isCandidateVersion)
+ .sorted(Comparator.comparing(IMigrationParticipant::getVersion))
+ .toList();
+ for (IMigrationParticipant migrationParticipant : migrationParticipantsCandidate) {
+ EStructuralFeature newStructuralFeature = migrationParticipant.getEStructuralFeature(eClass, eStructuralFeatureName);
+ if (newStructuralFeature != null) {
+ structuralFeature = newStructuralFeature;
+ }
+ }
+ return structuralFeature;
+ }
+
+ @Override
+ public EClassifier getType(EPackage ePackage, String typeName) {
+ EClassifier eClassifier = ePackage.getEClassifier(typeName);
+ var migrationParticipantsCandidate = migrationParticipants.stream()
+ .filter(this::isCandidateVersion)
+ .sorted(Comparator.comparing(IMigrationParticipant::getVersion))
+ .toList();
+ for (IMigrationParticipant migrationParticipant : migrationParticipantsCandidate) {
+ EClassifier newEClassifier = migrationParticipant.getEClassifier(ePackage, typeName);
+ if (newEClassifier != null) {
+ eClassifier = newEClassifier;
+ }
+ }
+ return eClassifier;
+ }
+
+ @Override
+ public EPackage getPackage(String nsURI) {
+ EPackage ePackage = super.getPackage(nsURI);
+ var migrationParticipantsCandidate = migrationParticipants.stream()
+ .filter(this::isCandidateVersion)
+ .sorted(Comparator.comparing(IMigrationParticipant::getVersion))
+ .toList();
+ for (IMigrationParticipant migrationParticipant : migrationParticipantsCandidate) {
+ EPackage newEPackage = migrationParticipant.getPackage(nsURI);
+ if (newEPackage != null) {
+ ePackage = newEPackage;
+ }
+ }
+ return ePackage;
+ }
+
+ @Override
+ public void preDeserialization(JsonResource resource, JsonObject jsonObject) {
+ this.setMigrationDataFromDocumentContent(jsonObject);
+ this.setResourceMetadataAdapterMigrationData(resource, this.documentMigrationData);
+ var migrationParticipantsCandidates = migrationParticipants.stream()
+ .filter(this::isCandidateVersion)
+ .sorted(Comparator.comparing(IMigrationParticipant::getVersion))
+ .toList();
+ for (IMigrationParticipant migrationParticipant : migrationParticipantsCandidates) {
+ migrationParticipant.preDeserialization(resource, jsonObject);
+ setResourceMetadataAdapterMigrationData(resource, new MigrationData(migrationParticipant.getClass().getSimpleName(), migrationParticipant.getVersion()));
+ }
+ }
+
+ @Override
+ public void postSerialization(JsonResource resource, JsonObject jsonObject) {
+ getOptionalResourceMetadataAdapter(resource).ifPresent(resourceMetadataAdapter -> {
+ if (resourceMetadataAdapter.getMigrationData() != null) {
+ var rootMigration = new Gson().toJsonTree(resourceMetadataAdapter.getMigrationData(), MigrationData.class);
+ if (rootMigration != null) {
+ jsonObject.add(MigrationData.JSON_OBJECT_ROOT, rootMigration);
+ }
+ }
+ });
+ var migrationParticipantsCandidates = migrationParticipants.stream()
+ .filter(this::isCandidateVersion)
+ .sorted(Comparator.comparing(IMigrationParticipant::getVersion))
+ .toList();
+ for (IMigrationParticipant migrationParticipant : migrationParticipantsCandidates) {
+ migrationParticipant.postSerialization(resource, jsonObject);
+ }
+ }
+
+ @Override
+ public void postObjectLoading(EObject eObject, JsonObject jsonObject, boolean isTopObject) {
+ var migrationParticipantsCandidates = migrationParticipants.stream()
+ .filter(this::isCandidateVersion)
+ .sorted(Comparator.comparing(IMigrationParticipant::getVersion))
+ .toList();
+ for (IMigrationParticipant migrationParticipant : migrationParticipantsCandidates) {
+ migrationParticipant.postObjectLoading(eObject, jsonObject);
+ }
+ }
+
+ @Override
+ public Object getValue(EObject object, EStructuralFeature feature, Object value) {
+ Object returnValue = value;
+ var migrationParticipantsCandidates = migrationParticipants.stream()
+ .filter(this::isCandidateVersion)
+ .sorted(Comparator.comparing(IMigrationParticipant::getVersion))
+ .toList();
+ for (IMigrationParticipant migrationParticipant : migrationParticipantsCandidates) {
+ Object newValue = migrationParticipant.getValue(object, feature, value);
+ if (newValue != null) {
+ returnValue = newValue;
+ }
+ }
+ return returnValue;
+ }
+
+ private Optional getOptionalResourceMetadataAdapter(JsonResource resource) {
+ return resource.eAdapters().stream()
+ .filter(ResourceMetadataAdapter.class::isInstance)
+ .map(ResourceMetadataAdapter.class::cast)
+ .findFirst();
+ }
+
+ private void setResourceMetadataAdapterMigrationData(JsonResource resource, MigrationData migrationData) {
+ getOptionalResourceMetadataAdapter(resource).ifPresent(resourceMetadataAdapter -> resourceMetadataAdapter.setMigrationData(migrationData));
+ }
+
+ private void setMigrationDataFromDocumentContent(JsonObject jsonObject) {
+ var optionalMigrationData = Optional.ofNullable(jsonObject.getAsJsonObject(MigrationData.JSON_OBJECT_ROOT))
+ .map(migrationRootElement -> new Gson().fromJson(migrationRootElement, MigrationData.class)).stream().findFirst();
+ optionalMigrationData.ifPresent(migrationData -> this.documentMigrationData = migrationData);
+ }
+}
diff --git a/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/migration/api/IMigrationParticipant.java b/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/migration/api/IMigrationParticipant.java
new file mode 100644
index 0000000000..686c9ed15d
--- /dev/null
+++ b/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/migration/api/IMigrationParticipant.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.components.emf.migration.api;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.sirius.emfjson.resource.JsonResource;
+
+import com.google.gson.JsonObject;
+
+/**
+ * Interface of MigrationParticipant.
+ *
+ * @author mcharfadi
+ */
+public interface IMigrationParticipant {
+ String getVersion();
+
+ /**
+ * Called before a JsonResource is serialized.
+ *
+ * @param resource
+ * The JsonResource that is serialized
+ * @param jsonObject
+ * The root jsonObject
+ */
+ default void preDeserialization(JsonResource resource, JsonObject jsonObject) {
+
+ }
+
+ /**
+ * Called after a JsonResource is serialized.
+ *
+ * @param resource
+ * The JsonResource that is serialized
+ * @param jsonObject
+ * The root jsonObject
+ */
+ default void postSerialization(JsonResource resource, JsonObject jsonObject) {
+
+ }
+
+ /**
+ * Called during the parsing of JsonResources after loading an eObject. As such the eObject will have all his
+ * features set. The jsonObject is the one that was used to set the features and can be used to retrieve values
+ * of unknown features.
+ *
+ * @param eObject
+ * the eObject that have been loaded.
+ * @param jsonObject
+ * the jsonObject used to load the eObject.
+ */
+ default void postObjectLoading(EObject eObject, JsonObject jsonObject) {
+
+ }
+
+ /**
+ * Called during the parsing of JsonResources (at loading time). If a feature value has changed since a previous
+ * version, use this method to return the correct expected value or null if it did not change.
+ *
+ * @param eObject
+ * the object containing the feature.
+ * @param feature
+ * the feature to set value.
+ * @param value
+ * the initial serialized value.
+ * @return the new value, or null otherwise.
+ */
+ default Object getValue(EObject eObject, EStructuralFeature feature, Object value) {
+ return null;
+ }
+
+ /**
+ * Called during the parsing of JsonResources (at loading time). It allows to
+ * retrieve a renamed EStructuralFeature from its old name. For example, if a
+ * feature 'aaa' has been renamed to 'bbb', then your MigrationParticipant
+ * should return the 'bbb' feature when given the 'aaa' name.
+ *
+ * @param eClass
+ * the given eClass.
+ * @param eStructuralFeatureName
+ * the feature name before migration.
+ * @return the new structural feature or null if not found. The attribute
+ * corresponding to given old name into given eClass.
+ */
+ default EStructuralFeature getEStructuralFeature(EClass eClass, String eStructuralFeatureName) {
+ return eClass.getEStructuralFeature(eStructuralFeatureName);
+ }
+
+ /**
+ * Called during the parsing of JsonResources (at loading time). If an
+ * EClassifier name has changed, then you should return the correct one.
+ *
+ * @param ePackage
+ * the package where looking for classifier.
+ * @param typeName
+ * the old classifier name before migration.
+ * @return the new classifier corresponding to the old given name into given
+ * ePackage or null if not found.
+ */
+ default EClassifier getEClassifier(EPackage ePackage, String typeName) {
+ return ePackage.getEClassifier(typeName);
+ }
+
+ /**
+ * Return the EPackage to use for the given namespace.
+ *
+ * @param nsURI
+ * the nsURI of the package we are looking for.
+ * @return an EPackage if some new mapping exists, null otherwise.
+ */
+ default EPackage getPackage(String nsURI) {
+ return null;
+ }
+}
diff --git a/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/migration/api/MigrationData.java b/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/migration/api/MigrationData.java
new file mode 100644
index 0000000000..364cb0a729
--- /dev/null
+++ b/packages/emf/backend/sirius-components-emf/src/main/java/org/eclipse/sirius/components/emf/migration/api/MigrationData.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.components.emf.migration.api;
+
+/**
+ * POJO for MigrationData.
+ *
+ * @author mcharfadi
+ */
+public record MigrationData(String lastMigrationPerformed, String migrationVersion) {
+
+ public static final String JSON_OBJECT_ROOT = "migration";
+
+ @Override
+ public String toString() {
+ return "MigrationData{" +
+ "lastMigrationPerformed='" + lastMigrationPerformed + '\'' +
+ ", migrationVersion='" + migrationVersion + '\'' +
+ '}';
+ }
+}
diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/document/services/DocumentSanitizedJsonContentProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/document/services/DocumentSanitizedJsonContentProvider.java
index 84b19496b5..af842f3934 100644
--- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/document/services/DocumentSanitizedJsonContentProvider.java
+++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/document/services/DocumentSanitizedJsonContentProvider.java
@@ -25,6 +25,8 @@
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.sirius.components.emf.migration.MigrationService;
+import org.eclipse.sirius.components.emf.migration.api.IMigrationParticipant;
import org.eclipse.sirius.components.emf.services.JSONResourceFactory;
import org.eclipse.sirius.emfjson.resource.JsonResource;
import org.eclipse.sirius.web.application.document.services.api.IDocumentSanitizedJsonContentProvider;
@@ -45,8 +47,11 @@ public class DocumentSanitizedJsonContentProvider implements IDocumentSanitizedJ
private final List externalResourceLoaderServices;
- public DocumentSanitizedJsonContentProvider(List externalResourceLoaderServices) {
+ private final List migrationParticipants;
+
+ public DocumentSanitizedJsonContentProvider(List externalResourceLoaderServices, List migrationParticipants) {
this.externalResourceLoaderServices = Objects.requireNonNull(externalResourceLoaderServices);
+ this.migrationParticipants = migrationParticipants;
}
@Override
@@ -63,10 +68,13 @@ public Optional getContent(ResourceSet resourceSet, String name, InputSt
ouputResource.getContents().addAll(inputResource.getContents());
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ var migrationExtendedMetaData = new MigrationService(this.migrationParticipants);
Map saveOptions = new HashMap<>();
saveOptions.put(JsonResource.OPTION_ENCODING, JsonResource.ENCODING_UTF_8);
saveOptions.put(JsonResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
saveOptions.put(JsonResource.OPTION_ID_MANAGER, new EObjectRandomIDManager());
+ saveOptions.put(JsonResource.OPTION_EXTENDED_META_DATA, migrationExtendedMetaData);
+ saveOptions.put(JsonResource.OPTION_JSON_RESSOURCE_PROCESSOR, migrationExtendedMetaData);
ouputResource.save(outputStream, saveOptions);
diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/document/services/JSONExternalResourceLoaderService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/document/services/JSONExternalResourceLoaderService.java
index 8075c2b5d8..d43b7edcb1 100644
--- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/document/services/JSONExternalResourceLoaderService.java
+++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/document/services/JSONExternalResourceLoaderService.java
@@ -19,12 +19,17 @@
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Optional;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.sirius.components.emf.migration.MigrationService;
+import org.eclipse.sirius.components.emf.migration.api.IMigrationParticipant;
import org.eclipse.sirius.components.emf.services.JSONResourceFactory;
+import org.eclipse.sirius.emfjson.resource.JsonResource;
import org.eclipse.sirius.web.application.document.services.api.IExternalResourceLoaderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,6 +45,12 @@ public class JSONExternalResourceLoaderService implements IExternalResourceLoade
private final Logger logger = LoggerFactory.getLogger(JSONExternalResourceLoaderService.class);
+ private final List migrationParticipants;
+
+ public JSONExternalResourceLoaderService(List migrationParticipants) {
+ this.migrationParticipants = migrationParticipants;
+ }
+
@Override
public boolean canHandle(InputStream inputStream, URI resourceURI, ResourceSet resourceSet) {
boolean canHandle = false;
@@ -61,9 +72,14 @@ public boolean canHandle(InputStream inputStream, URI resourceURI, ResourceSet r
public Optional getResource(InputStream inputStream, URI resourceURI, ResourceSet resourceSet) {
Resource resource = null;
try {
+ var migrationService = new MigrationService(this.migrationParticipants);
+ Map options = new HashMap<>();
+ options.put(JsonResource.OPTION_JSON_RESSOURCE_PROCESSOR, migrationService);
+ options.put(JsonResource.OPTION_EXTENDED_META_DATA, migrationService);
+
var jsonResource = new JSONResourceFactory().createResource(resourceURI);
resourceSet.getResources().add(jsonResource);
- jsonResource.load(inputStream, new HashMap<>());
+ jsonResource.load(inputStream, options);
resource = jsonResource;
} catch (IOException exception) {
diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/migration/participants/NodeDescriptionLabelExpressionMigrationParticipant.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/migration/participants/NodeDescriptionLabelExpressionMigrationParticipant.java
new file mode 100644
index 0000000000..430acf7d7a
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/migration/participants/NodeDescriptionLabelExpressionMigrationParticipant.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.application.editingcontext.migration.participants;
+
+import java.util.Optional;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.sirius.components.view.diagram.DiagramPackage;
+import org.eclipse.sirius.components.view.diagram.ImageNodeStyleDescription;
+import org.eclipse.sirius.components.view.diagram.InsideLabelDescription;
+import org.eclipse.sirius.components.view.diagram.NodeDescription;
+import org.eclipse.sirius.components.view.diagram.OutsideLabelDescription;
+import org.eclipse.sirius.components.view.diagram.RectangularNodeStyleDescription;
+import org.eclipse.sirius.components.emf.migration.api.IMigrationParticipant;
+
+import com.google.gson.JsonObject;
+import org.springframework.stereotype.Service;
+
+/**
+ * MigrationParticipant that update the LabelExpression of NodeDescription with
+ * InsideLabelDescription or OutsideLabelDescription.
+ *
+ * @author mcharfadi
+ */
+@Service
+public class NodeDescriptionLabelExpressionMigrationParticipant implements IMigrationParticipant {
+
+ private static final String PARTICIPANT_VERSION = "2024.4.0";
+
+ @Override
+ public String getVersion() {
+ return PARTICIPANT_VERSION;
+ }
+
+ @Override
+ public void postObjectLoading(EObject eObject, JsonObject jsonObject) {
+ if (eObject instanceof NodeDescription nodeDescription) {
+ var optionalNodeDescriptionData = Optional.ofNullable(jsonObject.getAsJsonObject("data"));
+ optionalNodeDescriptionData.ifPresent(nodeDescriptionData -> {
+ var optionalLabelExpression = Optional.ofNullable(nodeDescriptionData.get("labelExpression"));
+ optionalLabelExpression.ifPresent(labelExpression -> {
+ if (nodeDescription.getStyle() instanceof RectangularNodeStyleDescription) {
+ InsideLabelDescription insideLabelDescription = DiagramPackage.eINSTANCE.getDiagramFactory().createInsideLabelDescription();
+ insideLabelDescription.setLabelExpression(labelExpression.getAsString());
+ nodeDescription.setInsideLabel(insideLabelDescription);
+ }
+ if (nodeDescription.getStyle() instanceof ImageNodeStyleDescription) {
+ OutsideLabelDescription outsideLabelDescription = DiagramPackage.eINSTANCE.getDiagramFactory().createOutsideLabelDescription();
+ outsideLabelDescription.setLabelExpression(labelExpression.getAsString());
+ nodeDescription.getOutsideLabels().add(outsideLabelDescription);
+ }
+ });
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/ResourceLoader.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/ResourceLoader.java
index b6fca1918e..4c6127064d 100644
--- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/ResourceLoader.java
+++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/ResourceLoader.java
@@ -15,15 +15,25 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
import java.util.Optional;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.sirius.components.emf.migration.api.MigrationData;
import org.eclipse.sirius.components.emf.ResourceMetadataAdapter;
import org.eclipse.sirius.components.emf.services.JSONResourceFactory;
+import org.eclipse.sirius.emfjson.resource.JsonResource;
+import org.eclipse.sirius.components.emf.migration.api.IMigrationParticipant;
+import org.eclipse.sirius.components.emf.migration.MigrationService;
import org.eclipse.sirius.web.application.editingcontext.services.api.IResourceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
import org.springframework.stereotype.Service;
/**
@@ -36,16 +46,28 @@ public class ResourceLoader implements IResourceLoader {
private final Logger logger = LoggerFactory.getLogger(ResourceLoader.class);
+ private final List migrationParticipants;
+
+ public ResourceLoader(List migrationParticipants) {
+ this.migrationParticipants = migrationParticipants;
+ }
+
@Override
public Optional toResource(ResourceSet resourceSet, String id, String name, String content) {
Optional optionalResource = Optional.empty();
+ var migrationExtendedMetaData = new MigrationService(this.migrationParticipants);
+
+ HashMap