From 86cc3e7236c5315c4c34e47a80baa4c0b76b81ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20B=C3=A9gaudeau?= Date: Fri, 8 Mar 2024 17:54:03 +0100 Subject: [PATCH] [3019] Restore support for the discovery of domains and views model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: https://github.com/eclipse-sirius/sirius-web/issues/3019 Signed-off-by: Stéphane Bégaudeau --- .../emf/backend/sirius-components-emf/pom.xml | 2 +- .../backend/sirius-web-application/pom.xml | 5 + .../editingcontext/services/DocumentData.java | 25 +++++ .../services/DocumentToResourceService.java | 58 ++++++++++++ .../services/EPackageEntry.java | 21 +++++ .../EditingContextPersistenceService.java | 15 ++- .../services/EditingContextSearchService.java | 25 ++--- .../JsonResourceSerializationListener.java | 51 ++++++++++ .../services/ResourceToDocumentService.java | 12 ++- .../api/IDocumentToResourceService.java | 28 ++++++ .../api/IResourceToDocumentService.java | 4 +- .../EditingContextInitializerProvider.java | 94 +++++++++++++++++++ .../semanticdata/SemanticData.java | 22 ++++- .../semanticdata/SemanticDataDomain.java | 29 ++++++ .../repositories/ISemanticDataRepository.java | 11 +++ .../services/SemanticDataSearchService.java | 6 ++ .../services/SemanticDataUpdateService.java | 4 +- .../api/ISemanticDataSearchService.java | 3 + .../api/ISemanticDataUpdateService.java | 2 +- .../{2024.01 => 2024.3}/01-initial-schema.xml | 0 .../2024.3/02-store-semantic_data-domains.xml | 34 +++++++ .../db/changelog/2024.3/2024.3.0.xml | 20 ++++ .../main/resources/db/db.changelog-master.xml | 2 +- .../eclipse/sirius/web/TestIdentifiers.java | 2 +- ...tingContextControllerIntegrationTests.java | 8 +- .../ProjectControllerIntegrationTests.java | 2 +- .../services/DomainSearchServiceTests.java | 14 ++- .../StudioLifecycleIntegrationTests.java | 85 +++++++++++++++++ .../src/test/resources/scripts/cleanup.sql | 1 + .../src/test/resources/scripts/initialize.sql | 91 +++++++++++++++++- scripts/check-coverage.jsh | 10 +- 31 files changed, 632 insertions(+), 54 deletions(-) create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/DocumentData.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/DocumentToResourceService.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EPackageEntry.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/JsonResourceSerializationListener.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/api/IDocumentToResourceService.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/studio/services/EditingContextInitializerProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/SemanticDataDomain.java rename packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/{2024.01 => 2024.3}/01-initial-schema.xml (100%) create mode 100644 packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/02-store-semantic_data-domains.xml create mode 100644 packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/2024.3.0.xml create mode 100644 packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/services/StudioLifecycleIntegrationTests.java diff --git a/packages/emf/backend/sirius-components-emf/pom.xml b/packages/emf/backend/sirius-components-emf/pom.xml index 5c471a2b8a..533ba9caf9 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.6-SNAPSHOT + 2.3.7-SNAPSHOT org.springframework.boot diff --git a/packages/sirius-web/backend/sirius-web-application/pom.xml b/packages/sirius-web/backend/sirius-web-application/pom.xml index dc78a55be3..3a6ec273a4 100644 --- a/packages/sirius-web/backend/sirius-web-application/pom.xml +++ b/packages/sirius-web/backend/sirius-web-application/pom.xml @@ -144,6 +144,11 @@ sirius-components-view-gantt-edit 2024.1.5 + + org.eclipse.sirius + sirius-components-domain-emf + 2024.1.5 + diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/DocumentData.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/DocumentData.java new file mode 100644 index 0000000000..8ed8e57c82 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/DocumentData.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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.services; + +import java.util.List; + +import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.Document; + +/** + * The data retrieved from the serialization of a document. + * + * @author sbegaudeau + */ +public record DocumentData(Document document, List ePackageEntries) { +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/DocumentToResourceService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/DocumentToResourceService.java new file mode 100644 index 0000000000..c914dcc6c0 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/DocumentToResourceService.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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.services; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Optional; + +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.sirius.components.emf.ResourceMetadataAdapter; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; +import org.eclipse.sirius.web.application.editingcontext.services.api.IDocumentToResourceService; +import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.Document; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * Used to load documents as resources. + * + * @author sbegaudeau + */ +@Service +public class DocumentToResourceService implements IDocumentToResourceService { + + private final Logger logger = LoggerFactory.getLogger(DocumentToResourceService.class); + + @Override + public Optional toResource(ResourceSet resourceSet, Document document) { + Optional optionalResource = Optional.empty(); + + var resource = new JSONResourceFactory().createResourceFromPath(document.getId().toString()); + try (var inputStream = new ByteArrayInputStream(document.getContent().getBytes())) { + resourceSet.getResources().add(resource); + resource.load(inputStream, null); + + resource.eAdapters().add(new ResourceMetadataAdapter(document.getName())); + + optionalResource = Optional.of(resource); + } catch (IOException | IllegalArgumentException exception) { + this.logger.warn("An error occured while loading document {}: {}.", document.getId(), exception.getMessage()); + resourceSet.getResources().remove(resource); + } + + return optionalResource; + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EPackageEntry.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EPackageEntry.java new file mode 100644 index 0000000000..6f485ebd94 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EPackageEntry.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * 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.services; + +/** + * Used to store the EPackage used in a JsonResource. + * + * @author sbegaudeau + */ +public record EPackageEntry(String nsPrefix, String nsURI) { +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EditingContextPersistenceService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EditingContextPersistenceService.java index 6b8b5c5036..cc57b4c7b0 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EditingContextPersistenceService.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EditingContextPersistenceService.java @@ -12,6 +12,7 @@ *******************************************************************************/ package org.eclipse.sirius.web.application.editingcontext.services; +import java.util.LinkedHashSet; import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -24,6 +25,7 @@ import org.eclipse.sirius.web.application.UUIDParser; import org.eclipse.sirius.web.application.editingcontext.services.api.IResourceToDocumentService; import org.eclipse.sirius.web.domain.boundedcontexts.project.Project; +import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.Document; import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.services.api.ISemanticDataUpdateService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,11 +67,20 @@ public void persist(IEditingContext editingContext) { new UUIDParser().parse(editingContext.getId()) .map(AggregateReference::to) .ifPresent(project -> { - var documents = emfEditingContext.getDomain().getResourceSet().getResources().stream() + var documentData = emfEditingContext.getDomain().getResourceSet().getResources().stream() .map(this.resourceToDocumentService::toDocument) .flatMap(Optional::stream) .collect(Collectors.toSet()); - this.semanticDataUpdateService.updateDocuments(project, documents); + + var documents = new LinkedHashSet(); + var domainUris = new LinkedHashSet(); + + documentData.forEach(data -> { + documents.add(data.document()); + domainUris.addAll(data.ePackageEntries().stream().map(EPackageEntry::nsURI).toList()); + }); + + this.semanticDataUpdateService.updateDocuments(project, documents, domainUris); }); } diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EditingContextSearchService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EditingContextSearchService.java index 959afeb1e3..e6505c9415 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EditingContextSearchService.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/EditingContextSearchService.java @@ -12,8 +12,6 @@ *******************************************************************************/ package org.eclipse.sirius.web.application.editingcontext.services; -import java.io.ByteArrayInputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -28,12 +26,11 @@ import org.eclipse.sirius.components.core.api.IEditingContextProcessor; import org.eclipse.sirius.components.core.api.IEditingContextRepresentationDescriptionProvider; import org.eclipse.sirius.components.core.api.IEditingContextSearchService; -import org.eclipse.sirius.components.emf.ResourceMetadataAdapter; import org.eclipse.sirius.components.emf.services.EditingContextCrossReferenceAdapter; -import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.eclipse.sirius.web.application.UUIDParser; import org.eclipse.sirius.web.application.editingcontext.EditingContext; +import org.eclipse.sirius.web.application.editingcontext.services.api.IDocumentToResourceService; import org.eclipse.sirius.web.application.editingcontext.services.api.IEditingDomainFactory; import org.eclipse.sirius.web.domain.boundedcontexts.project.Project; import org.eclipse.sirius.web.domain.boundedcontexts.project.services.api.IProjectSearchService; @@ -63,6 +60,8 @@ public class EditingContextSearchService implements IEditingContextSearchService private final ISemanticDataSearchService semanticDataSearchService; + private final IDocumentToResourceService documentToResourceService; + private final IEditingDomainFactory editingDomainFactory; private final List representationDescriptionProviders; @@ -71,10 +70,11 @@ public class EditingContextSearchService implements IEditingContextSearchService private final Timer timer; - public EditingContextSearchService(IProjectSearchService projectSearchService, ISemanticDataSearchService semanticDataSearchService, IEditingDomainFactory editingDomainFactory, + public EditingContextSearchService(IProjectSearchService projectSearchService, ISemanticDataSearchService semanticDataSearchService, IDocumentToResourceService documentToResourceService, IEditingDomainFactory editingDomainFactory, List representationDescriptionProviders, List editingContextProcessors, MeterRegistry meterRegistry) { this.projectSearchService = Objects.requireNonNull(projectSearchService); this.semanticDataSearchService = Objects.requireNonNull(semanticDataSearchService); + this.documentToResourceService = Objects.requireNonNull(documentToResourceService); this.editingDomainFactory = Objects.requireNonNull(editingDomainFactory); this.representationDescriptionProviders = Objects.requireNonNull(representationDescriptionProviders); this.editingContextProcessors = Objects.requireNonNull(editingContextProcessors); @@ -125,20 +125,7 @@ private void loadSemanticData(EditingContext editingContext, SemanticData semant ResourceSet resourceSet = editingContext.getDomain().getResourceSet(); resourceSet.getLoadOptions().put(JsonResource.OPTION_SCHEMA_LOCATION, true); - var documents = semanticData.getDocuments(); - for (var document : documents) { - var resource = new JSONResourceFactory().createResourceFromPath(document.getId().toString()); - - try (var inputStream = new ByteArrayInputStream(document.getContent().getBytes())) { - resourceSet.getResources().add(resource); - resource.load(inputStream, null); - - resource.eAdapters().add(new ResourceMetadataAdapter(document.getName())); - } catch (IOException | IllegalArgumentException exception) { - this.logger.warn("An error occured while loading document {}: {}.", document.getId(), exception.getMessage()); - resourceSet.getResources().remove(resource); - } - } + semanticData.getDocuments().forEach(document -> this.documentToResourceService.toResource(resourceSet, document)); // The ECrossReferenceAdapter must be set after the resource loading because it needs to resolve proxies in case // of inter-resources references diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/JsonResourceSerializationListener.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/JsonResourceSerializationListener.java new file mode 100644 index 0000000000..a7d1c9ec37 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/JsonResourceSerializationListener.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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.services; + +import com.google.gson.JsonElement; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.sirius.emfjson.resource.JsonResource; + +/** + * Used to collect serialization data from JsonResource. + * + * @author sbegaudeau + */ +public class JsonResourceSerializationListener implements JsonResource.ISerializationListener { + + private final List ePackageEntries = new ArrayList<>(); + + @Override + public void onNsHeaderEntryAdded(String nsPrefix, String nsURI) { + this.ePackageEntries.add(new EPackageEntry(nsPrefix, nsURI)); + } + + @Override + public void onObjectSerialized(EObject eObject, JsonElement jsonElement) { + // Do nothing + } + + @Override + public void onCrossReferenceURICreated(EObject eObject, EReference eReference, String s) { + // Do nothing + } + + public List getePackageEntries() { + return this.ePackageEntries; + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/ResourceToDocumentService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/ResourceToDocumentService.java index b1b0793649..6cb3f0546c 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/ResourceToDocumentService.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/ResourceToDocumentService.java @@ -40,12 +40,15 @@ public class ResourceToDocumentService implements IResourceToDocumentService { private final Logger logger = LoggerFactory.getLogger(ResourceToDocumentService.class); @Override - public Optional toDocument(Resource resource) { + public Optional toDocument(Resource resource) { + var serializationListener = new JsonResourceSerializationListener(); + HashMap options = new HashMap<>(); options.put(JsonResource.OPTION_ID_MANAGER, new EObjectIDManager()); options.put(JsonResource.OPTION_SCHEMA_LOCATION, true); + options.put(JsonResource.OPTION_SERIALIZATION_LISTENER, serializationListener); - Optional optionalDocument = Optional.empty(); + Optional optionalDocumentData = Optional.empty(); try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { resource.save(outputStream, options); @@ -71,10 +74,11 @@ public Optional toDocument(Resource resource) { .name(name) .content(content) .build(); - optionalDocument = Optional.of(document); + var documentData = new DocumentData(document, serializationListener.getePackageEntries()); + optionalDocumentData = Optional.of(documentData); } catch (IllegalArgumentException | IOException exception) { this.logger.warn(exception.getMessage(), exception); } - return optionalDocument; + return optionalDocumentData; } } diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/api/IDocumentToResourceService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/api/IDocumentToResourceService.java new file mode 100644 index 0000000000..73e65f8a01 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/api/IDocumentToResourceService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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.services.api; + +import java.util.Optional; + +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.Document; + +/** + * Used to load documents as EMF resources. + * + * @author sbegaudeau + */ +public interface IDocumentToResourceService { + Optional toResource(ResourceSet resourceSet, Document document); +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/api/IResourceToDocumentService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/api/IResourceToDocumentService.java index 98eab1f169..a7e4cc0e2c 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/api/IResourceToDocumentService.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/editingcontext/services/api/IResourceToDocumentService.java @@ -15,7 +15,7 @@ import java.util.Optional; import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.Document; +import org.eclipse.sirius.web.application.editingcontext.services.DocumentData; /** * Used to transform an EMF resource into a document. @@ -23,5 +23,5 @@ * @author sbegaudeau */ public interface IResourceToDocumentService { - Optional toDocument(Resource resource); + Optional toDocument(Resource resource); } diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/studio/services/EditingContextInitializerProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/studio/services/EditingContextInitializerProvider.java new file mode 100644 index 0000000000..f04bc63854 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/studio/services/EditingContextInitializerProvider.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * 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.studio.services; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IEditingContextProcessor; +import org.eclipse.sirius.components.domain.Domain; +import org.eclipse.sirius.components.domain.DomainPackage; +import org.eclipse.sirius.components.domain.emf.DomainConverter; +import org.eclipse.sirius.components.emf.services.EditingContextCrossReferenceAdapter; +import org.eclipse.sirius.components.view.View; +import org.eclipse.sirius.components.view.ViewPackage; +import org.eclipse.sirius.components.view.deck.DeckPackage; +import org.eclipse.sirius.components.view.diagram.DiagramPackage; +import org.eclipse.sirius.components.view.form.FormPackage; +import org.eclipse.sirius.components.view.gantt.GanttPackage; +import org.eclipse.sirius.web.application.editingcontext.EditingContext; +import org.eclipse.sirius.web.application.editingcontext.services.api.IDocumentToResourceService; +import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.services.api.ISemanticDataSearchService; +import org.springframework.stereotype.Service; + +/** + * Used to contribute the domain and view models found to the editing context. + * + * @author sbegaudeau + */ +@Service +public class EditingContextInitializerProvider implements IEditingContextProcessor { + + private final ISemanticDataSearchService semanticDataSearchService; + + private final IDocumentToResourceService documentToResourceService; + + public EditingContextInitializerProvider(ISemanticDataSearchService semanticDataSearchService, IDocumentToResourceService documentToResourceService) { + this.semanticDataSearchService = Objects.requireNonNull(semanticDataSearchService); + this.documentToResourceService = Objects.requireNonNull(documentToResourceService); + } + + @Override + public void preProcess(IEditingContext editingContext) { + if (editingContext instanceof EditingContext siriusWebEditingContext) { + List domains = new ArrayList<>(); + List views = new ArrayList<>(); + + var allSemanticData = this.semanticDataSearchService.findAllByDomains(List.of(DomainPackage.eNS_URI, ViewPackage.eNS_URI)); + for (var semanticData: allSemanticData) { + ResourceSet resourceSet = new ResourceSetImpl(); + + resourceSet.getPackageRegistry().put(DomainPackage.eNS_URI, DomainPackage.eINSTANCE); + resourceSet.getPackageRegistry().put(ViewPackage.eNS_URI, ViewPackage.eINSTANCE); + resourceSet.getPackageRegistry().put(DeckPackage.eNS_URI, DeckPackage.eINSTANCE); + resourceSet.getPackageRegistry().put(DiagramPackage.eNS_URI, DiagramPackage.eINSTANCE); + resourceSet.getPackageRegistry().put(FormPackage.eNS_URI, FormPackage.eINSTANCE); + resourceSet.getPackageRegistry().put(GanttPackage.eNS_URI, GanttPackage.eINSTANCE); + + semanticData.getDocuments().forEach(document -> this.documentToResourceService.toResource(resourceSet, document)); + resourceSet.eAdapters().add(new EditingContextCrossReferenceAdapter()); + + var treeIterator = resourceSet.getAllContents(); + while (treeIterator.hasNext()) { + var next = treeIterator.next(); + if (next instanceof View view) { + views.add(view); + treeIterator.prune(); + } else if (next instanceof Domain domain) { + domains.add(domain); + treeIterator.prune(); + } + } + } + + siriusWebEditingContext.getViews().addAll(views); + + var resourceSet = siriusWebEditingContext.getDomain().getResourceSet(); + new DomainConverter().convert(domains).forEach(ePackage -> resourceSet.getPackageRegistry().put(ePackage.getNsURI(), ePackage)); + } + } +} diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/SemanticData.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/SemanticData.java index a03828271c..66eb41fd7b 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/SemanticData.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/SemanticData.java @@ -13,11 +13,13 @@ package org.eclipse.sirius.web.domain.boundedcontexts.semanticdata; import java.time.Instant; +import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Objects; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import org.eclipse.sirius.web.domain.boundedcontexts.AbstractValidatingAggregateRoot; import org.eclipse.sirius.web.domain.boundedcontexts.project.Project; @@ -51,6 +53,9 @@ public class SemanticData extends AbstractValidatingAggregateRoot @MappedCollection(idColumn = "semantic_data_id") private Set documents = new LinkedHashSet<>(); + @MappedCollection(idColumn = "semantic_data_id") + private Set domains = new LinkedHashSet<>(); + private Instant createdOn; private Instant lastModifiedOn; @@ -81,8 +86,11 @@ public boolean isNew() { return this.isNew; } - public void updateDocuments(Set newDocuments) { + public void updateDocuments(Set newDocuments, Set domainUris) { this.documents = newDocuments; + this.domains = domainUris.stream() + .map(SemanticDataDomain::new) + .collect(Collectors.toSet()); this.lastModifiedOn = Instant.now(); this.registerEvent(new SemanticDataUpdatedEvent(UUID.randomUUID(), this.lastModifiedOn, this)); @@ -103,6 +111,8 @@ public static final class Builder { private Set documents = new LinkedHashSet<>(); + private Set domains = new LinkedHashSet<>(); + public Builder project(AggregateReference project) { this.project = Objects.requireNonNull(project); return this; @@ -113,13 +123,21 @@ public Builder documents(Set documents) { return this; } + public Builder domains(Collection domains) { + this.domains = domains.stream() + .map(SemanticDataDomain::new) + .collect(Collectors.toSet()); + return this; + } + public SemanticData build() { var semanticData = new SemanticData(); semanticData.isNew = true; semanticData.id = UUID.randomUUID(); - semanticData.project = Objects.requireNonNull(project); + semanticData.project = Objects.requireNonNull(this.project); semanticData.documents = Objects.requireNonNull(this.documents); + semanticData.domains = Objects.requireNonNull(this.domains); var now = Instant.now(); semanticData.createdOn = now; diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/SemanticDataDomain.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/SemanticDataDomain.java new file mode 100644 index 0000000000..291e6cc330 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/SemanticDataDomain.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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.domain.boundedcontexts.semanticdata; + +import java.util.Objects; + +import org.springframework.data.relational.core.mapping.Table; + +/** + * A domain used by semantic data. + * + * @author sbegaudeau + */ +@Table("semantic_data_domain") +public record SemanticDataDomain(String uri) { + public SemanticDataDomain { + Objects.requireNonNull(uri); + } +} diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/repositories/ISemanticDataRepository.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/repositories/ISemanticDataRepository.java index 042d42a9c6..f574ea52c6 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/repositories/ISemanticDataRepository.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/repositories/ISemanticDataRepository.java @@ -12,6 +12,7 @@ *******************************************************************************/ package org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.repositories; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -42,4 +43,14 @@ CASE WHEN count(*)> 0 THEN true ELSE false END WHERE semanticData.project_id = :projectId """) Optional findByProjectId(UUID projectId); + + @Query(""" + SELECT semanticData.* + FROM semantic_data semanticData + JOIN semantic_data_domain semanticDataDomain + ON semanticData.id = semanticDataDomain.semantic_data_id + WHERE semanticDataDomain.uri IN (:domainUris) + GROUP BY semanticData.id + """) + List findAllByDomains(List domainUris); } diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/SemanticDataSearchService.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/SemanticDataSearchService.java index e44125ad0a..1e5357524b 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/SemanticDataSearchService.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/SemanticDataSearchService.java @@ -12,6 +12,7 @@ *******************************************************************************/ package org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.services; +import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -46,4 +47,9 @@ public boolean existsByProject(AggregateReference project) { public Optional findByProject(AggregateReference project) { return this.semanticDataRepository.findByProjectId(project.getId()); } + + @Override + public List findAllByDomains(List domainUris) { + return this.semanticDataRepository.findAllByDomains(domainUris); + } } diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/SemanticDataUpdateService.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/SemanticDataUpdateService.java index 61215aa509..bfe10953ae 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/SemanticDataUpdateService.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/SemanticDataUpdateService.java @@ -38,9 +38,9 @@ public SemanticDataUpdateService(ISemanticDataRepository semanticDataRepository) } @Override - public void updateDocuments(AggregateReference project, Set documents) { + public void updateDocuments(AggregateReference project, Set documents, Set domainUris) { this.semanticDataRepository.findByProjectId(project.getId()).ifPresent(semanticData -> { - semanticData.updateDocuments(documents); + semanticData.updateDocuments(documents, domainUris); this.semanticDataRepository.save(semanticData); }); } diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/api/ISemanticDataSearchService.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/api/ISemanticDataSearchService.java index 1429373616..17cb5ff99c 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/api/ISemanticDataSearchService.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/api/ISemanticDataSearchService.java @@ -12,6 +12,7 @@ *******************************************************************************/ package org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.services.api; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -29,4 +30,6 @@ public interface ISemanticDataSearchService { boolean existsByProject(AggregateReference project); Optional findByProject(AggregateReference project); + + List findAllByDomains(List domainUris); } diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/api/ISemanticDataUpdateService.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/api/ISemanticDataUpdateService.java index 291896f034..e21ce407a2 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/api/ISemanticDataUpdateService.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/semanticdata/services/api/ISemanticDataUpdateService.java @@ -25,5 +25,5 @@ * @author sbegaudeau */ public interface ISemanticDataUpdateService { - void updateDocuments(AggregateReference project, Set documents); + void updateDocuments(AggregateReference project, Set documents, Set domainUris); } diff --git a/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.01/01-initial-schema.xml b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/01-initial-schema.xml similarity index 100% rename from packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.01/01-initial-schema.xml rename to packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/01-initial-schema.xml diff --git a/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/02-store-semantic_data-domains.xml b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/02-store-semantic_data-domains.xml new file mode 100644 index 0000000000..53f9e6a3eb --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/02-store-semantic_data-domains.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + ALTER TABLE semantic_data_domain ADD CONSTRAINT semantic_data_domain_uri_length CHECK (char_length(uri) > 0) + + + \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/2024.3.0.xml b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/2024.3.0.xml new file mode 100644 index 0000000000..634dcb72d2 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/changelog/2024.3/2024.3.0.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/db.changelog-master.xml b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/db.changelog-master.xml index 4729f3381d..35d64ad96a 100644 --- a/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/db.changelog-master.xml +++ b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/db/db.changelog-master.xml @@ -15,5 +15,5 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd"> - + \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/TestIdentifiers.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/TestIdentifiers.java index a1ecf28a90..a9cd6a4b52 100644 --- a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/TestIdentifiers.java +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/TestIdentifiers.java @@ -22,7 +22,7 @@ public interface TestIdentifiers { UUID INVALID_PROJECT = UUID.fromString("a2bed581-9661-41bf-9217-2870a9dce67c"); - UUID STUDIO_PROJECT = UUID.fromString("250cabc0-a211-438c-8015-2d2aa136eb81"); + UUID EMPTY_STUDIO_PROJECT = UUID.fromString("250cabc0-a211-438c-8015-2d2aa136eb81"); UUID UML_SAMPLE_PROJECT = UUID.fromString("7ba7bda7-13b9-422a-838b-e45a3597e952"); UUID SYSML_SAMPLE_PROJECT = UUID.fromString("4164c661-e0cb-4071-b25d-8516440bb8e8"); UUID ECORE_SAMPLE_PROJECT = UUID.fromString("99d336a2-3049-439a-8853-b104ffb22653"); diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/EditingContextControllerIntegrationTests.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/EditingContextControllerIntegrationTests.java index 827e2280c5..65370df4fe 100644 --- a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/EditingContextControllerIntegrationTests.java +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/EditingContextControllerIntegrationTests.java @@ -183,7 +183,7 @@ public void givenEditingContextIdWhenQueryIsPerformedThenItsActionsAreReturned() @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) public void givenProjectWhenAnEditingContextActionIsInvokedThenTheEditingContextIsModified() { - var editingContextEventInput = new EditingContextEventInput(UUID.randomUUID(), TestIdentifiers.STUDIO_PROJECT.toString()); + var editingContextEventInput = new EditingContextEventInput(UUID.randomUUID(), TestIdentifiers.EMPTY_STUDIO_PROJECT.toString()); var flux = this.graphQLRequestor.subscribe(GET_EDITING_CONTEXT_EVENT_SUBSCRIPTION, editingContextEventInput); @@ -198,9 +198,9 @@ public void givenProjectWhenAnEditingContextActionIsInvokedThenTheEditingContext assertThat(typename).isEqualTo(SuccessPayload.class.getSimpleName()); }; - var createEmptyDomainInput = new InvokeEditingContextActionInput(UUID.randomUUID(), TestIdentifiers.STUDIO_PROJECT.toString(), StudioEditingContextActionProvider.EMPTY_DOMAIN_ID); - var createEmptyViewInput = new InvokeEditingContextActionInput(UUID.randomUUID(), TestIdentifiers.STUDIO_PROJECT.toString(), StudioEditingContextActionProvider.EMPTY_VIEW_ID); - var createEmptyDocumentInput = new InvokeEditingContextActionInput(UUID.randomUUID(), TestIdentifiers.STUDIO_PROJECT.toString(), DefaultEditingContextActionProvider.EMPTY_ACTION_ID); + var createEmptyDomainInput = new InvokeEditingContextActionInput(UUID.randomUUID(), TestIdentifiers.EMPTY_STUDIO_PROJECT.toString(), StudioEditingContextActionProvider.EMPTY_DOMAIN_ID); + var createEmptyViewInput = new InvokeEditingContextActionInput(UUID.randomUUID(), TestIdentifiers.EMPTY_STUDIO_PROJECT.toString(), StudioEditingContextActionProvider.EMPTY_VIEW_ID); + var createEmptyDocumentInput = new InvokeEditingContextActionInput(UUID.randomUUID(), TestIdentifiers.EMPTY_STUDIO_PROJECT.toString(), DefaultEditingContextActionProvider.EMPTY_ACTION_ID); StepVerifier.create(flux) .then(() -> invokeEditingContextActionTask.accept(createEmptyDomainInput)) .then(() -> invokeEditingContextActionTask.accept(createEmptyViewInput)) diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/ProjectControllerIntegrationTests.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/ProjectControllerIntegrationTests.java index 970cfe914b..840fba2df7 100644 --- a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/ProjectControllerIntegrationTests.java +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/ProjectControllerIntegrationTests.java @@ -206,7 +206,7 @@ public void givenSetOfProjectsWhenQueryIsPerformedThenTheProjectsAreReturned() { assertThat(endCursor).isNotBlank(); int count = JsonPath.read(result, "$.data.viewer.projects.pageInfo.count"); - assertThat(count).isEqualTo(4); + assertThat(count).isEqualTo(5); List projectIds = JsonPath.read(result, "$.data.viewer.projects.edges[*].node.id"); assertThat(projectIds).hasSize(2); diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/services/DomainSearchServiceTests.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/services/DomainSearchServiceTests.java index 022dc828e3..c3d57ad17f 100644 --- a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/services/DomainSearchServiceTests.java +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/services/DomainSearchServiceTests.java @@ -51,11 +51,10 @@ public void givenSemanticDataWhenEditingContextIsLoadedThenDomainsCanBeRetrieved var editingContext = optionalEditingContext.get(); var domains = this.domainSearchService.findAllByEditingContext(editingContext); - assertThat(domains).hasSize(1); + assertThat(domains).isNotEmpty(); - var firstDomain = domains.get(0); - assertThat(firstDomain.getId()).isEqualTo(EcorePackage.eNS_URI); - assertThat(firstDomain.getLabel()).isEqualTo(EcorePackage.eNS_URI); + var hasEcore = domains.stream().anyMatch(domain -> domain.getId().equals(EcorePackage.eNS_URI)); + assertThat(hasEcore).isTrue(); } @Test @@ -68,10 +67,9 @@ public void givenSemanticDataWhenEditingContextIsLoadedThenRootDomainsCanBeRetri var editingContext = optionalEditingContext.get(); var rootDomains = this.domainSearchService.findRootDomainsByEditingContext(editingContext); - assertThat(rootDomains).hasSize(1); + assertThat(rootDomains).isNotEmpty(); - var firstDomain = rootDomains.get(0); - assertThat(firstDomain.getId()).isEqualTo(EcorePackage.eNS_URI); - assertThat(firstDomain.getLabel()).isEqualTo(EcorePackage.eNS_URI); + var hasEcore = rootDomains.stream().anyMatch(domain -> domain.getId().equals(EcorePackage.eNS_URI)); + assertThat(hasEcore).isTrue(); } } diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/services/StudioLifecycleIntegrationTests.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/services/StudioLifecycleIntegrationTests.java new file mode 100644 index 0000000000..c4706597ab --- /dev/null +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/services/StudioLifecycleIntegrationTests.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * 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.services; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import org.eclipse.sirius.components.core.api.IEditingContextSearchService; +import org.eclipse.sirius.components.view.form.FormDescription; +import org.eclipse.sirius.web.AbstractIntegrationTests; +import org.eclipse.sirius.web.TestIdentifiers; +import org.eclipse.sirius.web.application.editingcontext.EditingContext; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.SqlConfig; +import org.springframework.transaction.annotation.Transactional; + +/** + * Integration tests of the lifecycle of the studios. + * + * @author sbegaudeau + */ +@Transactional +@SuppressWarnings("checkstyle:MultipleStringLiterals") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class StudioLifecycleIntegrationTests extends AbstractIntegrationTests { + + @Autowired + private IEditingContextSearchService editingContextSearchService; + + @Test + @DisplayName("Given a regular project, when it is loaded, then the domains from all studios are available") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenRegularProjectWhenItIsLoadedThenTheDomainsFromAllStudiosAreAvailable() { + var optionalEditingContext = this.editingContextSearchService.findById(TestIdentifiers.ECORE_SAMPLE_PROJECT.toString()); + assertThat(optionalEditingContext).isPresent(); + + var editingContext = optionalEditingContext.get(); + if (editingContext instanceof EditingContext siriusWebEditingContext) { + var ePackageRegistry = siriusWebEditingContext.getDomain().getResourceSet().getPackageRegistry(); + var ePackage = ePackageRegistry.get("domain://buck"); + assertThat(ePackage).isNotNull(); + } else { + fail("Invalid editing context"); + } + } + + @Test + @DisplayName("Given a regularProject, when it is loaded, then the views from all studios are available") + @Sql(scripts = {"/scripts/initialize.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenRegularProjectWhenItIsLoadedThenTheViewsFromAllStudiosAreAvailable() { + var optionalEditingContext = this.editingContextSearchService.findById(TestIdentifiers.ECORE_SAMPLE_PROJECT.toString()); + assertThat(optionalEditingContext).isPresent(); + + var editingContext = optionalEditingContext.get(); + if (editingContext instanceof EditingContext siriusWebEditingContext) { + var views = siriusWebEditingContext.getViews(); + assertThat(views).hasSize(1); + + var view = views.get(0); + assertThat(view.getDescriptions()).hasSize(1); + + var viewRepresentationDescription = view.getDescriptions().get(0); + assertThat(viewRepresentationDescription).isInstanceOf(FormDescription.class); + assertThat(viewRepresentationDescription.getName()).isEqualTo("Human Form"); + } else { + fail("Invalid editing context"); + } + } +} diff --git a/packages/sirius-web/backend/sirius-web/src/test/resources/scripts/cleanup.sql b/packages/sirius-web/backend/sirius-web/src/test/resources/scripts/cleanup.sql index 68e441c938..260115aac8 100644 --- a/packages/sirius-web/backend/sirius-web/src/test/resources/scripts/cleanup.sql +++ b/packages/sirius-web/backend/sirius-web/src/test/resources/scripts/cleanup.sql @@ -1,4 +1,5 @@ DELETE FROM document; +DELETE FROM semantic_data_domain; DELETE FROM semantic_data; DELETE FROM representation_data; DELETE FROM nature; diff --git a/packages/sirius-web/backend/sirius-web/src/test/resources/scripts/initialize.sql b/packages/sirius-web/backend/sirius-web/src/test/resources/scripts/initialize.sql index eb38dfb2ff..274ccaca53 100644 --- a/packages/sirius-web/backend/sirius-web/src/test/resources/scripts/initialize.sql +++ b/packages/sirius-web/backend/sirius-web/src/test/resources/scripts/initialize.sql @@ -6,7 +6,7 @@ INSERT INTO project ( last_modified_on ) VALUES ( '250cabc0-a211-438c-8015-2d2aa136eb81', - 'Studio', + 'Empty Studio', '2024-01-01 9:42:0.000', '2024-01-02 9:42:0.000' ); @@ -29,6 +29,88 @@ INSERT INTO semantic_data ( '2024-01-02 9:42:0.000' ); +-- Sample studio project +INSERT INTO project ( + id, + name, + created_on, + last_modified_on +) VALUES ( + '01234836-0902-418a-900a-4c0afd20323e', + 'Studio', + '2024-01-01 9:42:0.000', + '2024-01-02 9:42:0.000' +); +INSERT INTO nature ( + project_id, + name +) VALUES ( + '01234836-0902-418a-900a-4c0afd20323e', + 'siriusComponents://nature?kind=studio' +); +INSERT INTO semantic_data ( + id, + project_id, + created_on, + last_modified_on +) VALUES ( + 'e344d967-a639-4f6c-9c00-a466d51063c6', + '01234836-0902-418a-900a-4c0afd20323e', + '2024-01-01 9:42:0.000', + '2024-01-02 9:42:0.000' +); +INSERT INTO semantic_data_domain ( + semantic_data_id, + uri +) VALUES ( + 'e344d967-a639-4f6c-9c00-a466d51063c6', + 'http://www.eclipse.org/sirius-web/domain' +); +INSERT INTO semantic_data_domain ( + semantic_data_id, + uri +) VALUES ( + 'e344d967-a639-4f6c-9c00-a466d51063c6', + 'http://www.eclipse.org/sirius-web/view' +); +INSERT INTO semantic_data_domain ( + semantic_data_id, + uri +) VALUES ( + 'e344d967-a639-4f6c-9c00-a466d51063c6', + 'http://www.eclipse.org/sirius-web/form' +); +INSERT INTO document ( + id, + semantic_data_id, + name, + content, + created_on, + last_modified_on +) VALUES ( + 'f0e490c1-79f1-49a0-b1f2-3637f2958148', + 'e344d967-a639-4f6c-9c00-a466d51063c6', + 'Domain', + '{"json":{"version":"1.0","encoding":"utf-8"},"ns":{"domain":"http://www.eclipse.org/sirius-web/domain"},"content":[{"id":"f8204cb6-3705-48a5-bee3-ad7e7d6cbdaf","eClass":"domain:Domain","data":{"name":"buck","types":[{"id":"c341bf91-d315-4264-9787-c51b121a6375","eClass":"domain:Entity","data":{"name":"Root","attributes":[{"id":"7ac92c9d-3cb6-4374-9774-11bb62962fe2","eClass":"domain:Attribute","data":{"name":"label"}}],"relations":[{"id":"f8fefc5d-4fee-4666-815e-94b24a95183f","eClass":"domain:Relation","data":{"name":"humans","many":true,"containment":true,"targetType":"//@types.1"}}]}},{"id":"1731ffb5-bfb0-46f3-a23d-0c0650300005","eClass":"domain:Entity","data":{"name":"Human","attributes":[{"id":"e34109d2-f51b-4070-af0e-da8b31c1f830","eClass":"domain:Attribute","data":{"name":"name"}},{"id":"e86d3f45-d043-441e-b8ab-12e4b3f8915a","eClass":"domain:Attribute","data":{"name":"description"}},{"id":"703e6db4-a193-4da7-a872-6efba2b3a2c5","eClass":"domain:Attribute","data":{"name":"promoted","type":"BOOLEAN"}}]}}]}}]}', + '2024-01-01 9:42:0.000', + '2024-01-02 9:42:0.000' +); +INSERT INTO document ( + id, + semantic_data_id, + name, + content, + created_on, + last_modified_on +) VALUES ( + 'ed2a5355-991d-458f-87f1-ea3a18b1f104', + 'e344d967-a639-4f6c-9c00-a466d51063c6', + 'Form View', + '{"json":{"version":"1.0","encoding":"utf-8"},"ns":{"form":"http://www.eclipse.org/sirius-web/form","view":"http://www.eclipse.org/sirius-web/view"},"content":[{"id":"c4591605-8ea8-4e92-bb17-05c4538248f8","eClass":"view:View","data":{"descriptions":[{"id":"ed20cb85-a58a-47ad-bc0d-749ec8b2ea03","eClass":"form:FormDescription","data":{"name":"Human Form","domainType":"buck::Human","pages":[{"id":"b0c73654-6f1b-4be5-832d-b97f053b5196","eClass":"form:PageDescription","data":{"name":"Human","labelExpression":"aql:self.name","domainType":"buck::Human","groups":[{"id":"28d8d6de-7d6f-4434-9293-0ac4ef2461ac","eClass":"form:GroupDescription","data":{"name":"Properties","labelExpression":"Properties","children":[{"id":"b02b89b7-6c06-40f8-9366-83d5f885ada1","eClass":"form:TextfieldDescription","data":{"name":"Name","labelExpression":"Name","helpExpression":"The name of the human","valueExpression":"aql:self.name","body":[{"id":"ecdc23ff-fd4b-47a4-939d-1bc03e656d3d","eClass":"view:ChangeContext","data":{"children":[{"id":"a8b95d5b-833a-4b19-b783-3025225613de","eClass":"view:SetValue","data":{"featureName":"name","valueExpression":"aql:newValue"}}]}}]}},{"id":"98e756a2-305f-4767-b75c-4130996ae6da","eClass":"form:TextAreaDescription","data":{"name":"Description","labelExpression":"Description","helpExpression":"The description of the human","valueExpression":"aql:self.description","body":[{"id":"59ea57d5-c365-4421-9648-f38a74644768","eClass":"view:ChangeContext","data":{"children":[{"id":"811bb719-ab53-49ea-9281-6558f7022ecc","eClass":"view:SetValue","data":{"featureName":"description","valueExpression":"aql:newValue"}}]}}]}},{"id":"ba20babb-0e75-4f66-a382-a2f02bce904a","eClass":"form:CheckboxDescription","data":{"name":"Promoted","labelExpression":"Promoted","helpExpression":"Has this human been promoted?","valueExpression":"aql:self.promoted","body":[{"id":"afac13bd-71ac-4287-baf6-3669f23ac806","eClass":"view:ChangeContext","data":{"children":[{"id":"0eaeca64-ee2b-4f2c-9454-c528181d0d64","eClass":"view:SetValue","data":{"featureName":"promoted","valueExpression":"aql:newValue"}}]}}]}}]}}]}}]}}]}}]}', + '2024-01-01 9:42:0.000', + '2024-01-02 9:42:0.000' +); + -- Sample empty UML project INSERT INTO project ( id, @@ -121,6 +203,13 @@ INSERT INTO semantic_data ( '2024-01-01 9:42:0.000', '2024-01-02 9:42:0.000' ); +INSERT INTO semantic_data_domain ( + semantic_data_id, + uri +) VALUES ( + 'cb133bf0-d7aa-4a83-a277-0972919dd46a', + 'http://www.eclipse.org/emf/2002/Ecore' +); INSERT INTO document ( id, semantic_data_id, diff --git a/scripts/check-coverage.jsh b/scripts/check-coverage.jsh index daccf50b6f..00a3ccfb97 100644 --- a/scripts/check-coverage.jsh +++ b/scripts/check-coverage.jsh @@ -33,7 +33,7 @@ var moduleCoverageData = List.of( new ModuleCoverage("sirius-components-annotations", 0.0), new ModuleCoverage("sirius-components-annotations-spring", 0.0), new ModuleCoverage("sirius-components-representations", 76.0), - new ModuleCoverage("sirius-components-core", 61.0), + new ModuleCoverage("sirius-components-core", 62.0), new ModuleCoverage("sirius-components-collaborative", 83.0), new ModuleCoverage("sirius-components-graphql-api", 46.0), new ModuleCoverage("sirius-components-charts", 52.0), @@ -50,8 +50,8 @@ var moduleCoverageData = List.of( new ModuleCoverage("sirius-components-forms", 81.0), new ModuleCoverage("sirius-components-collaborative-forms", 82.0), new ModuleCoverage("sirius-components-forms-graphql", 53.0), - new ModuleCoverage("sirius-components-widget-reference", 62.0), - new ModuleCoverage("sirius-components-collaborative-widget-reference", 49.0), + new ModuleCoverage("sirius-components-widget-reference", 70.0), + new ModuleCoverage("sirius-components-collaborative-widget-reference", 54.0), new ModuleCoverage("sirius-components-widget-reference-graphql", 28.0), new ModuleCoverage("sirius-components-formdescriptioneditors", 18.0), new ModuleCoverage("sirius-components-collaborative-formdescriptioneditors", 83.0), @@ -93,9 +93,9 @@ var moduleCoverageData = List.of( new ModuleCoverage("sirius-components-view-deck-edit", 4.0), new ModuleCoverage("sirius-components-view-emf", 57.0), new ModuleCoverage("sirius-components-view-builder", 13.0), - new ModuleCoverage("sirius-components-task", 36.0), + new ModuleCoverage("sirius-components-task", 47.0), new ModuleCoverage("sirius-components-task-edit", 3.0), - new ModuleCoverage("sirius-components-task-starter", 12.0), + new ModuleCoverage("sirius-components-task-starter", 41.0), new ModuleCoverage("sirius-components-flow-starter", 78.0), new ModuleCoverage("sirius-web-customwidgets", 57.0), new ModuleCoverage("sirius-web-customwidgets-edit", 7.0),