From 7d97d31874f004a6ec9bb83030d296c35248c78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20B=C3=A9gaudeau?= Date: Wed, 21 Feb 2024 10:57:44 +0100 Subject: [PATCH] [3019] Prepare support for the onboard area on the new architecture 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 --- ...tingContextRepresentationsDataFetcher.java | 72 +++++++++++++++++++ .../RepresentationApplicationService.java | 26 +++++++ .../IRepresentationApplicationService.java | 4 ++ .../IRepresentationDataRepository.java | 8 +++ .../RepresentationDataSearchService.java | 7 ++ .../api/IRepresentationDataSearchService.java | 4 ++ ...resentationControllerIntegrationTests.java | 58 +++++++++++++++ 7 files changed, 179 insertions(+) create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/controllers/EditingContextRepresentationsDataFetcher.java diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/controllers/EditingContextRepresentationsDataFetcher.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/controllers/EditingContextRepresentationsDataFetcher.java new file mode 100644 index 0000000000..5484087211 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/controllers/EditingContextRepresentationsDataFetcher.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * 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.representation.controllers; + +import java.util.Objects; + +import org.eclipse.sirius.components.annotations.spring.graphql.QueryDataFetcher; +import org.eclipse.sirius.components.core.RepresentationMetadata; +import org.eclipse.sirius.components.graphql.api.IDataFetcherWithFieldCoordinates; +import org.eclipse.sirius.web.application.dto.PageInfoWithCount; +import org.eclipse.sirius.web.application.representation.services.api.IRepresentationApplicationService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; + +import graphql.relay.Connection; +import graphql.relay.ConnectionCursor; +import graphql.relay.DefaultConnection; +import graphql.relay.DefaultConnectionCursor; +import graphql.relay.DefaultEdge; +import graphql.relay.Edge; +import graphql.relay.Relay; +import graphql.schema.DataFetchingEnvironment; + +/** + * Data fetcher for the field EditingContext#representations. + * + * @author sbegaudeau + */ +@QueryDataFetcher(type = "EditingContext", field = "representations") +public class EditingContextRepresentationsDataFetcher implements IDataFetcherWithFieldCoordinates> { + + private final IRepresentationApplicationService representationApplicationService; + + public EditingContextRepresentationsDataFetcher(IRepresentationApplicationService representationApplicationService) { + this.representationApplicationService = Objects.requireNonNull(representationApplicationService); + } + + @Override + public Connection get(DataFetchingEnvironment environment) throws Exception { + String editingContextId = environment.getSource(); + var representationMetadataPage = this.representationApplicationService.findAllByEditingContextId(editingContextId, PageRequest.of(0, 20)); + return this.toConnection(representationMetadataPage); + } + + private Connection toConnection(Page representationMetadataPage) { + var edges = representationMetadataPage.stream().map(representationMetadata -> { + var globalId = new Relay().toGlobalId("RepresentationMetadata", representationMetadata.getId()); + var cursor = new DefaultConnectionCursor(globalId); + return (Edge) new DefaultEdge<>(representationMetadata, cursor); + }).toList(); + + ConnectionCursor startCursor = edges.stream().findFirst() + .map(Edge::getCursor) + .orElse(null); + ConnectionCursor endCursor = null; + if (!edges.isEmpty()) { + endCursor = edges.get(edges.size() - 1).getCursor(); + } + var pageInfo = new PageInfoWithCount(startCursor, endCursor, representationMetadataPage.hasPrevious(), representationMetadataPage.hasNext(), representationMetadataPage.getTotalElements()); + return new DefaultConnection<>(edges, pageInfo); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/services/RepresentationApplicationService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/services/RepresentationApplicationService.java index 5bd6d27123..21ece3294c 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/services/RepresentationApplicationService.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/services/RepresentationApplicationService.java @@ -12,14 +12,22 @@ *******************************************************************************/ package org.eclipse.sirius.web.application.representation.services; +import java.util.Comparator; +import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.UUID; import org.eclipse.sirius.components.core.RepresentationMetadata; import org.eclipse.sirius.web.application.UUIDParser; import org.eclipse.sirius.web.application.representation.services.api.IRepresentationApplicationService; +import org.eclipse.sirius.web.domain.boundedcontexts.project.Project; import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.RepresentationData; import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.services.api.IRepresentationDataSearchService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -45,6 +53,24 @@ public Optional findRepresentationMetadataById(String re .map(this::toRepresentationMetadata); } + @Override + public Page findAllByEditingContextId(String editingContextId, Pageable pageable) { + var representationData = new UUIDParser().parse(editingContextId) + .map(AggregateReference::to) + .map(this.representationDataSearchService::findAllByProject) + .orElse(List.of()) + .stream() + .sorted(Comparator.comparing(RepresentationData::getLabel)) + .toList(); + + int startIndex = (int) pageable.getOffset() * pageable.getPageSize(); + int endIndex = Math.min(((int) pageable.getOffset() + 1) * pageable.getPageSize(), representationData.size()); + var representationMetadata = representationData.subList(startIndex, endIndex).stream() + .map(this::toRepresentationMetadata) + .toList(); + return new PageImpl<>(representationMetadata, pageable, representationData.size()); + } + private RepresentationMetadata toRepresentationMetadata(RepresentationData representationData) { return new RepresentationMetadata(representationData.getId().toString(), representationData.getKind(), representationData.getLabel(), representationData.getDescriptionId()); } diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/services/api/IRepresentationApplicationService.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/services/api/IRepresentationApplicationService.java index fe757bb8a1..4d4380bda9 100644 --- a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/services/api/IRepresentationApplicationService.java +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/representation/services/api/IRepresentationApplicationService.java @@ -15,6 +15,8 @@ import java.util.Optional; import org.eclipse.sirius.components.core.RepresentationMetadata; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; /** * Used to interact with representations. @@ -23,4 +25,6 @@ */ public interface IRepresentationApplicationService { Optional findRepresentationMetadataById(String representationId); + + Page findAllByEditingContextId(String editingContextId, Pageable pageable); } diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/repositories/IRepresentationDataRepository.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/repositories/IRepresentationDataRepository.java index a10795b9fe..62c6ade1a1 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/repositories/IRepresentationDataRepository.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/repositories/IRepresentationDataRepository.java @@ -12,9 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.web.domain.boundedcontexts.representationdata.repositories; +import java.util.List; import java.util.UUID; import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.RepresentationData; +import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.repository.ListCrudRepository; import org.springframework.data.repository.ListPagingAndSortingRepository; import org.springframework.stereotype.Repository; @@ -26,4 +28,10 @@ */ @Repository public interface IRepresentationDataRepository extends ListPagingAndSortingRepository, ListCrudRepository { + @Query(""" + SELECT * + FROM representation_data representationData + WHERE representationData.project_id = :projectId + """) + List findAllByProjectId(UUID projectId); } diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/services/RepresentationDataSearchService.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/services/RepresentationDataSearchService.java index ed34865d11..453793ca75 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/services/RepresentationDataSearchService.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/services/RepresentationDataSearchService.java @@ -17,9 +17,11 @@ import java.util.Optional; import java.util.UUID; +import org.eclipse.sirius.web.domain.boundedcontexts.project.Project; import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.RepresentationData; import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.repositories.IRepresentationDataRepository; import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.services.api.IRepresentationDataSearchService; +import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.stereotype.Service; /** @@ -41,6 +43,11 @@ public Optional findById(UUID id) { return this.representationDataRepository.findById(id); } + @Override + public List findAllByProject(AggregateReference project) { + return this.representationDataRepository.findAllByProjectId(project.getId()); + } + @Override public List findAllByTargetObjectId(String targetObjectId) { return List.of(); diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/services/api/IRepresentationDataSearchService.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/services/api/IRepresentationDataSearchService.java index bc9dbc6d21..752eb74b41 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/services/api/IRepresentationDataSearchService.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/boundedcontexts/representationdata/services/api/IRepresentationDataSearchService.java @@ -16,7 +16,9 @@ import java.util.Optional; import java.util.UUID; +import org.eclipse.sirius.web.domain.boundedcontexts.project.Project; import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.RepresentationData; +import org.springframework.data.jdbc.core.mapping.AggregateReference; /** * Used to find representation data. @@ -26,5 +28,7 @@ public interface IRepresentationDataSearchService { Optional findById(UUID id); + List findAllByProject(AggregateReference project); + List findAllByTargetObjectId(String targetObjectId); } diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/RepresentationControllerIntegrationTests.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/RepresentationControllerIntegrationTests.java index c17d6419e5..9169ed33d2 100644 --- a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/RepresentationControllerIntegrationTests.java +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/RepresentationControllerIntegrationTests.java @@ -16,6 +16,7 @@ import com.jayway.jsonpath.JsonPath; +import java.util.List; import java.util.Map; import org.eclipse.sirius.web.AbstractIntegrationTests; @@ -52,6 +53,31 @@ query getRepresentationMetadata($editingContextId: ID!, $representationId: ID!) } """; + private static final String GET_ALL_REPRESENTATION_METADATA_QUERY = """ + query getAllRepresentationMetadata($editingContextId: ID!) { + viewer { + editingContext(editingContextId: $editingContextId) { + representations { + edges { + node { + id + label + kind + } + } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + count + } + } + } + } + } + """; + @Autowired private IGraphQLRequestor graphQLRequestor; @@ -75,4 +101,36 @@ public void givenRepresentationIdWhenQueryIsPerformedThenTheRepresentationMetada String label = JsonPath.read(result, "$.data.viewer.editingContext.representation.label"); assertThat(label).isEqualTo("Portal"); } + + @Test + @DisplayName("Given an editing context id, when a query is performed, then all the representation metadata are returned") + @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 givenEditingContextIdWhenQueryIsPerformedThenAllTheRepresentationMetadataAreReturned() { + Map variables = Map.of( + "editingContextId", TestIdentifiers.ECORE_SAMPLE_PROJECT.toString() + ); + var result = this.graphQLRequestor.execute(GET_ALL_REPRESENTATION_METADATA_QUERY, variables); + + boolean hasPreviousPage = JsonPath.read(result, "$.data.viewer.editingContext.representations.pageInfo.hasPreviousPage"); + assertThat(hasPreviousPage).isFalse(); + + boolean hasNextPage = JsonPath.read(result, "$.data.viewer.editingContext.representations.pageInfo.hasNextPage"); + assertThat(hasNextPage).isFalse(); + + String startCursor = JsonPath.read(result, "$.data.viewer.editingContext.representations.pageInfo.startCursor"); + assertThat(startCursor).isNotBlank(); + + String endCursor = JsonPath.read(result, "$.data.viewer.editingContext.representations.pageInfo.endCursor"); + assertThat(endCursor).isNotBlank(); + + int count = JsonPath.read(result, "$.data.viewer.editingContext.representations.pageInfo.count"); + assertThat(count).isEqualTo(1); + + List representationIds = JsonPath.read(result, "$.data.viewer.editingContext.representations.edges[*].node.id"); + assertThat(representationIds).hasSize(1); + + var firstRepresentationId = representationIds.get(0); + assertThat(firstRepresentationId).isEqualTo(TestIdentifiers.EPACKAGE_PORTAL_REPRESENTATION.toString()); + } }