diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index a9db109900..54f26bbd56 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -13,6 +13,7 @@ - https://github.com/eclipse-sirius/sirius-components/issues/1897[1897] [diagram] ToolSection are not using records - https://github.com/eclipse-sirius/sirius-components/issues/1616[#1616] [core] Use Java records for all our payloads +- https://github.com/eclipse-sirius/sirius-components/issues/1848[#1848] [project] Remove the frontend dependency to `uuid` in favor of `crypto.randomUUID` - https://github.com/eclipse-sirius/sirius-components/issues/1907[#1907] [view] The management of colors is changing, it is not possible anymore to use color directly represented by a string in the _styleDescription_. All the colors are now defined in a new palette object _ColorPalette_ with the properties _name_ and _value_. A view can define as many _ColorPalette_ as desired. @@ -24,13 +25,12 @@ In the _styleDescription_, the definition of a color are now a select list of al - https://github.com/eclipse-sirius/sirius-components/issues/265[#265] [core] Switch to the latest release of AQL -- https://github.com/eclipse-sirius/sirius-components/issues/1848[#1848] [project] Remove the frontend dependency to `uuid` in favor of `crypto.randomUUID` - === Bug fixes - https://github.com/eclipse-sirius/sirius-components/issues/1304[#1304] [tree] Fix an issue where dropping an element from the tree to a diagram used the current selection instead of the dragged tree item. - https://github.com/eclipse-sirius/sirius-components/issues/1839[#1839] [view] Remove default AQL expression on Create Edge and Create Node since they did not work anymore. - https://github.com/eclipse-sirius/sirius-components/issues/1940[#1940] [sirius-web] Remove duplicated spring-boot-starter-test dependency in sirius-web-sample-application +- https://github.com/eclipse-sirius/sirius-components/issues/1952[#1952] [view] Fix a regression introduced in 2023.4.0 where View-based Forms could no longer be instanciated === New Features diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/papaya/view/PapayaViewProvider.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/papaya/view/PapayaViewProvider.java index 05bf663c51..ce8a6384c8 100644 --- a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/papaya/view/PapayaViewProvider.java +++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/papaya/view/PapayaViewProvider.java @@ -43,6 +43,7 @@ import org.eclipse.sirius.web.sample.papaya.view.operationalanalysis.OperationalActorNodeDescriptionProvider; import org.eclipse.sirius.web.sample.papaya.view.operationalanalysis.OperationalEntityNodeDescriptionProvider; import org.eclipse.sirius.web.sample.papaya.view.operationalanalysis.OperationalPerimeterNodeDescriptionProvider; +import org.eclipse.sirius.web.sample.papaya.view.overviewform.OverviewFormProvider; /** * Used to create the test view. @@ -125,6 +126,9 @@ public View getView() { var classDiagramDescription = new ClassDiagramDescriptionProvider().create(colorProvider); view.getDescriptions().add(classDiagramDescription); + var overviewFormDescription = new OverviewFormProvider().create(colorProvider); + view.getDescriptions().add(overviewFormDescription); + return view; } diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/papaya/view/overviewform/OverviewFormProvider.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/papaya/view/overviewform/OverviewFormProvider.java new file mode 100644 index 0000000000..f9b91e0f15 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/papaya/view/overviewform/OverviewFormProvider.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2023 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.sample.papaya.view.overviewform; + +import org.eclipse.sirius.components.view.RepresentationDescription; +import org.eclipse.sirius.components.view.ViewFactory; +import org.eclipse.sirius.web.sample.papaya.view.IColorProvider; +import org.eclipse.sirius.web.sample.papaya.view.IRepresentationDescriptionProvider; + +/** + * Used to create the description of the overview form. + * + * @author sbegaudeau + */ +public class OverviewFormProvider implements IRepresentationDescriptionProvider { + @Override + public RepresentationDescription create(IColorProvider colorProvider) { + var formDescription = ViewFactory.eINSTANCE.createFormDescription(); + formDescription.setDomainType("papaya_core::Root"); + formDescription.setName("Overview Form"); + + var groupDescription = ViewFactory.eINSTANCE.createGroupDescription(); + groupDescription.setName("Group"); + groupDescription.setSemanticCandidatesExpression("aql:self"); + groupDescription.setLabelExpression("Root"); + + formDescription.getGroups().add(groupDescription); + + return formDescription; + } +} diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/test/java/org/eclipse/sirius/web/sample/tests/integration/view/ViewFormIntegrationTests.java b/packages/sirius-web/backend/sirius-web-sample-application/src/test/java/org/eclipse/sirius/web/sample/tests/integration/view/ViewFormIntegrationTests.java new file mode 100644 index 0000000000..4d434af982 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-sample-application/src/test/java/org/eclipse/sirius/web/sample/tests/integration/view/ViewFormIntegrationTests.java @@ -0,0 +1,317 @@ +/******************************************************************************* + * Copyright (c) 2023 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.sample.tests.integration.view; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.jayway.jsonpath.JsonPath; + +import java.time.Duration; +import java.util.Map; +import java.util.UUID; +import java.util.function.Predicate; + +import org.eclipse.sirius.components.collaborative.dto.CreateRepresentationInput; +import org.eclipse.sirius.components.collaborative.dto.CreateRootObjectInput; +import org.eclipse.sirius.components.collaborative.editingcontext.EditingContextEventProcessorRegistry; +import org.eclipse.sirius.components.collaborative.forms.api.FormConfiguration; +import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; +import org.eclipse.sirius.components.collaborative.forms.dto.FormEventInput; +import org.eclipse.sirius.components.collaborative.forms.dto.FormRefreshedEventPayload; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.components.graphql.api.IEventProcessorSubscriptionProvider; +import org.eclipse.sirius.web.persistence.repositories.IProjectRepository; +import org.eclipse.sirius.web.sample.configuration.StereotypeDescriptionRegistryConfigurer; +import org.eclipse.sirius.web.sample.papaya.PapayaStudioTemplateProvider; +import org.eclipse.sirius.web.sample.tests.integration.AbstractIntegrationTests; +import org.eclipse.sirius.web.services.api.document.CreateDocumentInput; +import org.eclipse.sirius.web.services.api.projects.CreateProjectFromTemplateInput; +import org.eclipse.sirius.web.services.api.projects.CreateProjectInput; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import graphql.ExecutionInput; +import graphql.GraphQL; +import reactor.test.StepVerifier; + +/** + * Integration tests of a form representation based on the view DSL. + * + * @author sbegaudeau + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SuppressWarnings("checkstyle:MultipleStringLiterals") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ViewFormIntegrationTests extends AbstractIntegrationTests { + @Autowired + private GraphQL graphQL; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private IProjectRepository projectRepository; + + @Autowired + private EditingContextEventProcessorRegistry editingContextEventProcessorRegistry; + + @Autowired + private IEventProcessorSubscriptionProvider eventProcessorSubscriptionProvider; + + private UUID projectId; + + private UUID rootObjectId; + + private UUID representationId; + + @BeforeEach + public void setup() { + this.createStudio(); + this.createProject(); + this.createProjectContent(); + this.createForm(); + } + + @AfterEach + public void teardown() { + this.editingContextEventProcessorRegistry.dispose(); + this.projectRepository.deleteAll(); + } + + private void createStudio() { + var query = """ + mutation createProjectFromTemplate($input: CreateProjectFromTemplateInput!) { + createProjectFromTemplate(input: $input) { + __typename + } + } + """; + + var input = new CreateProjectFromTemplateInput(UUID.randomUUID(), PapayaStudioTemplateProvider.STUDIO_TEMPLATE_ID); + + var executionInput = ExecutionInput.newExecutionInput() + .query(query) + .variables(Map.of("input", this.objectMapper.convertValue(input, new TypeReference>() { }))) + .build(); + var executionResult = this.graphQL.execute(executionInput); + assertThat(executionResult.getErrors()).isEmpty(); + + try { + var jsonResult = this.objectMapper.writeValueAsString(executionResult.toSpecification()); + String responseTypeName = JsonPath.read(jsonResult, "$.data.createProjectFromTemplate.__typename"); + assertThat(responseTypeName).isEqualTo("CreateProjectFromTemplateSuccessPayload"); + } catch (JsonProcessingException exception) { + fail(exception.getMessage()); + } + } + + private void createProject() { + var query = """ + mutation createProject($input: CreateProjectInput!) { + createProject(input: $input) { + __typename + ... on CreateProjectSuccessPayload { + project { + id + } + } + } + } + """; + + var input = new CreateProjectInput(UUID.randomUUID(), "Instance"); + + var executionInput = ExecutionInput.newExecutionInput() + .query(query) + .variables(Map.of("input", this.objectMapper.convertValue(input, new TypeReference>() { }))) + .build(); + var executionResult = this.graphQL.execute(executionInput); + assertThat(executionResult.getErrors()).isEmpty(); + + try { + var jsonResult = this.objectMapper.writeValueAsString(executionResult.toSpecification()); + String responseTypeName = JsonPath.read(jsonResult, "$.data.createProject.__typename"); + assertThat(responseTypeName).isEqualTo("CreateProjectSuccessPayload"); + + String rawProjectId = JsonPath.read(jsonResult, "$.data.createProject.project.id"); + this.projectId = UUID.fromString(rawProjectId); + } catch (JsonProcessingException | IllegalArgumentException exception) { + fail(exception.getMessage()); + } + + assertThat(this.projectRepository.existsById(this.projectId)).isTrue(); + } + + private void createProjectContent() { + var createDocumentQuery = """ + mutation createDocument($input: CreateDocumentInput!) { + createDocument(input: $input) { + __typename + ... on CreateDocumentSuccessPayload { + document { + id + } + } + } + } + """; + + assertThat(this.projectRepository.existsById(this.projectId)).isTrue(); + + var createDocumentInput = new CreateDocumentInput(UUID.randomUUID(), this.projectId.toString(), "New", StereotypeDescriptionRegistryConfigurer.EMPTY_ID); + + var createDocumentExecutionInput = ExecutionInput.newExecutionInput() + .query(createDocumentQuery) + .variables(Map.of("input", this.objectMapper.convertValue(createDocumentInput, new TypeReference>() { }))) + .build(); + var createDocumentExecutionResult = this.graphQL.execute(createDocumentExecutionInput); + assertThat(createDocumentExecutionResult.getErrors()).isEmpty(); + + UUID documentId = null; + try { + var jsonResult = this.objectMapper.writeValueAsString(createDocumentExecutionResult.toSpecification()); + String responseTypeName = JsonPath.read(jsonResult, "$.data.createDocument.__typename"); + assertThat(responseTypeName).isEqualTo("CreateDocumentSuccessPayload"); + + String rawDocumentId = JsonPath.read(jsonResult, "$.data.createDocument.document.id"); + documentId = UUID.fromString(rawDocumentId); + } catch (JsonProcessingException | IllegalArgumentException exception) { + fail(exception.getMessage()); + } + + var createRootObjectQuery = """ + mutation createRootObject($input: CreateRootObjectInput!) { + createRootObject(input: $input) { + __typename + ... on CreateRootObjectSuccessPayload { + object { + id + } + } + } + } + """; + + var createRootObjectInput = new CreateRootObjectInput(UUID.randomUUID(), this.projectId.toString(), documentId, "domain://papaya_core", "Root"); + + var createRootObjectExecutionInput = ExecutionInput.newExecutionInput() + .query(createRootObjectQuery) + .variables(Map.of("input", this.objectMapper.convertValue(createRootObjectInput, new TypeReference>() { }))) + .build(); + var createRootObjectExecutionResult = this.graphQL.execute(createRootObjectExecutionInput); + assertThat(createRootObjectExecutionResult.getErrors()).isEmpty(); + + try { + var jsonResult = this.objectMapper.writeValueAsString(createRootObjectExecutionResult.toSpecification()); + String responseTypeName = JsonPath.read(jsonResult, "$.data.createRootObject.__typename"); + assertThat(responseTypeName).isEqualTo("CreateRootObjectSuccessPayload"); + + String rawObjectId = JsonPath.read(jsonResult, "$.data.createRootObject.object.id"); + this.rootObjectId = UUID.fromString(rawObjectId); + } catch (JsonProcessingException exception) { + fail(exception.getMessage()); + } + } + + private void createForm() { + var getRepresentationDescriptionsQuery = """ + query getRepresentationDescriptions($editingContextId: ID!, $objectId: ID!) { + viewer { + editingContext(editingContextId: $editingContextId) { + representationDescriptions(objectId: $objectId) { + edges { + node { + id + } + } + } + } + } + } + """; + + var getRepresentationDescriptionsExecutionInput = ExecutionInput.newExecutionInput() + .query(getRepresentationDescriptionsQuery) + .variables(Map.of("editingContextId", this.projectId.toString(), "objectId", this.rootObjectId.toString())) + .build(); + var getRepresentationDescriptionsExecutionResult = this.graphQL.execute(getRepresentationDescriptionsExecutionInput); + assertThat(getRepresentationDescriptionsExecutionResult.getErrors()).isEmpty(); + + String representationDescriptionId = null; + try { + var jsonResult = this.objectMapper.writeValueAsString(getRepresentationDescriptionsExecutionResult.toSpecification()); + representationDescriptionId = JsonPath.read(jsonResult, "$.data.viewer.editingContext.representationDescriptions.edges[1].node.id"); + } catch (JsonProcessingException exception) { + fail(exception.getMessage()); + } + + var query = """ + mutation createRepresentation($input: CreateRepresentationInput!) { + createRepresentation(input: $input) { + __typename + ... on CreateRepresentationSuccessPayload { + representation { + id + } + } + } + } + """; + + var input = new CreateRepresentationInput(UUID.randomUUID(), this.projectId.toString(), representationDescriptionId, this.rootObjectId.toString(), "Form"); + var executionInput = ExecutionInput.newExecutionInput() + .query(query) + .variables(Map.of("input", this.objectMapper.convertValue(input, new TypeReference>() { }))) + .build(); + var executionResult = this.graphQL.execute(executionInput); + assertThat(executionResult.getErrors()).isEmpty(); + + try { + var jsonResult = this.objectMapper.writeValueAsString(executionResult.toSpecification()); + String rawRepresentationId = JsonPath.read(jsonResult, "$.data.createRepresentation.representation.id"); + this.representationId = UUID.fromString(rawRepresentationId); + } catch (JsonProcessingException | IllegalArgumentException exception) { + fail(exception.getMessage()); + } + } + + @Test + @DisplayName("Given a domain and a view, when a document and a representation are created, then we can subscribe to the representation") + public void givenDomainAndViewWhenDocumentAndRepresentationAreCreatedThenWeCanSubscribeToTheRepresentation() { + var configuration = new FormConfiguration(this.representationId.toString()); + var input = new FormEventInput(UUID.randomUUID(), this.projectId.toString(), this.representationId.toString()); + var payloadFlux = this.eventProcessorSubscriptionProvider.getSubscription(this.projectId.toString(), IFormEventProcessor.class, configuration, input); + + Predicate isEmptyFormRefreshedEventPayload = payload -> { + if (payload instanceof FormRefreshedEventPayload formRefreshedEventPayload) { + var form = formRefreshedEventPayload.form(); + return form.getPages().size() == 1; + } + return false; + }; + + StepVerifier.create(payloadFlux) + .expectNextMatches(isEmptyFormRefreshedEventPayload) + .thenCancel() + .verify(Duration.ofSeconds(5)); + } +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/ViewRepresentationDescriptionSearchService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/ViewRepresentationDescriptionSearchService.java index 147f893aeb..103461286d 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/ViewRepresentationDescriptionSearchService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/ViewRepresentationDescriptionSearchService.java @@ -27,16 +27,18 @@ import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.sirius.components.core.api.IURLParser; import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.core.api.IURLParser; import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.components.view.DiagramDescription; import org.eclipse.sirius.components.view.EdgeDescription; +import org.eclipse.sirius.components.view.FormDescription; import org.eclipse.sirius.components.view.NodeDescription; import org.eclipse.sirius.components.view.RepresentationDescription; import org.eclipse.sirius.components.view.View; import org.eclipse.sirius.components.view.emf.IViewRepresentationDescriptionSearchService; import org.eclipse.sirius.components.view.emf.diagram.IDiagramIdProvider; +import org.eclipse.sirius.components.view.emf.form.IFormIdProvider; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.eclipse.sirius.web.persistence.entities.DocumentEntity; import org.eclipse.sirius.web.persistence.repositories.IDocumentRepository; @@ -64,13 +66,16 @@ public class ViewRepresentationDescriptionSearchService implements IViewRepresen private final IURLParser urlParser; + private final IFormIdProvider formIdProvider; + private final IObjectService objectService; - public ViewRepresentationDescriptionSearchService(IDocumentRepository documentRepository, EPackage.Registry ePackageRegistry, IDiagramIdProvider diagramIdProvider, IURLParser urlParser, IObjectService objectService) { + public ViewRepresentationDescriptionSearchService(IDocumentRepository documentRepository, EPackage.Registry ePackageRegistry, IDiagramIdProvider diagramIdProvider, IURLParser urlParser, IFormIdProvider formIdProvider, IObjectService objectService) { this.urlParser = Objects.requireNonNull(urlParser); this.documentRepository = Objects.requireNonNull(documentRepository); this.ePackageRegistry = Objects.requireNonNull(ePackageRegistry); this.diagramIdProvider = Objects.requireNonNull(diagramIdProvider); + this.formIdProvider = Objects.requireNonNull(formIdProvider); this.objectService = Objects.requireNonNull(objectService); } @@ -156,11 +161,16 @@ private Stream getViewDefinitions(Resource resource) { } private String getRepresentationDescriptionId(RepresentationDescription description) { + String result; if (description instanceof DiagramDescription diagramDescription) { - return this.diagramIdProvider.getId(diagramDescription); + result = this.diagramIdProvider.getId(diagramDescription); + } else if (description instanceof FormDescription formDescription) { + result = this.formIdProvider.getId(formDescription); + } else { + String descriptionURI = EcoreUtil.getURI(description).toString(); + result = UUID.nameUUIDFromBytes(descriptionURI.getBytes()).toString(); } - String descriptionURI = EcoreUtil.getURI(description).toString(); - return UUID.nameUUIDFromBytes(descriptionURI.getBytes()).toString(); + return result; } public Optional findNodeDescriptionById(DiagramDescription diagramDescription, String nodeDescriptionId) { diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/IRepresentationDescriptionIdProvider.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/IRepresentationDescriptionIdProvider.java new file mode 100644 index 0000000000..5c6e5753b8 --- /dev/null +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/IRepresentationDescriptionIdProvider.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2023 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.view.emf; + +import org.eclipse.sirius.components.view.RepresentationDescription; + +/** + * Used to provide the id of a representation description. + * + * @author sbegaudeau + * + * @param The type of representation description supported. + */ +public interface IRepresentationDescriptionIdProvider { + + String PREFIX = "siriusComponents://representationDescription"; + + String KIND = "kind"; + + String SOURCE_KIND = "sourceKind"; + + String VIEW_SOURCE_KIND = "view"; + + String SOURCE_ID = "sourceId"; + + String SOURCE_ELEMENT_ID = "sourceElementId"; + + String getId(T representationDescription); + +} diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/IViewRepresentationDescriptionPredicate.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/IViewRepresentationDescriptionPredicate.java new file mode 100644 index 0000000000..fc548d65ca --- /dev/null +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/IViewRepresentationDescriptionPredicate.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2023 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.view.emf; + +import java.util.function.Predicate; + +import org.eclipse.sirius.components.representations.IRepresentationDescription; + +/** + * Used to test if a representation description has been created by the view converter. + * + * @author sbegaudeau + */ +public interface IViewRepresentationDescriptionPredicate extends Predicate { +} diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewConverter.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewConverter.java index be9c8027d2..c86e820cc3 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewConverter.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewConverter.java @@ -64,16 +64,14 @@ public List convert(List views, List views.forEach(view -> { AQLInterpreter interpreter = this.createInterpreter(view, visibleEPackages); try { - // @formatter:off result.addAll(view.getDescriptions().stream() .map(representationDescription -> this.convert(representationDescription, allViewsRepresentationDescriptions, interpreter)) .flatMap(Optional::stream) .toList()); - - // @formatter:on - } catch (NullPointerException e) { + } catch (NullPointerException exception) { // Can easily happen if the View model is currently invalid/inconsistent, typically because it is // currently being created or edited. + this.logger.debug("Exception while converting view", exception); } }); return result; diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewRepresentationDescriptionPredicate.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewRepresentationDescriptionPredicate.java new file mode 100644 index 0000000000..f840dc7a83 --- /dev/null +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewRepresentationDescriptionPredicate.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2023 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.view.emf; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import org.eclipse.sirius.components.core.api.IURLParser; +import org.eclipse.sirius.components.representations.IRepresentationDescription; +import org.springframework.stereotype.Service; + +/** + * Used to test if a representation description has been created by the view converter. + * + * @author sbegaudeau + */ +@Service +public class ViewRepresentationDescriptionPredicate implements IViewRepresentationDescriptionPredicate { + + private final IURLParser urlParser; + + public ViewRepresentationDescriptionPredicate(IURLParser urlParser) { + this.urlParser = Objects.requireNonNull(urlParser); + } + + @Override + public boolean test(IRepresentationDescription representationDescription) { + if (representationDescription.getId().startsWith(IRepresentationDescriptionIdProvider.PREFIX)) { + Map> parameters = this.urlParser.getParameterValues(representationDescription.getId()); + List values = Optional.ofNullable(parameters.get(IRepresentationDescriptionIdProvider.SOURCE_KIND)).orElse(List.of()); + return values.contains(IRepresentationDescriptionIdProvider.VIEW_SOURCE_KIND); + } + return false; + } +} diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewRepresentationDescriptionsProvider.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewRepresentationDescriptionsProvider.java index d0f78716d5..9bf46cd428 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewRepresentationDescriptionsProvider.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/ViewRepresentationDescriptionsProvider.java @@ -14,22 +14,18 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Objects; -import java.util.Optional; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EPackage.Registry; import org.eclipse.sirius.components.collaborative.api.IRepresentationDescriptionsProvider; import org.eclipse.sirius.components.collaborative.api.RepresentationDescriptionMetadata; import org.eclipse.sirius.components.core.api.IEditingContext; -import org.eclipse.sirius.components.core.api.IURLParser; import org.eclipse.sirius.components.emf.services.EditingContext; import org.eclipse.sirius.components.interpreter.AQLInterpreter; import org.eclipse.sirius.components.representations.IRepresentationDescription; import org.eclipse.sirius.components.representations.VariableManager; import org.eclipse.sirius.components.view.View; -import org.eclipse.sirius.components.view.emf.diagram.IDiagramIdProvider; import org.springframework.stereotype.Service; /** @@ -44,22 +40,17 @@ public class ViewRepresentationDescriptionsProvider implements IRepresentationDe private final List javaServiceProviders; - private final IURLParser urlParser; + private final IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate; - public ViewRepresentationDescriptionsProvider(IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService, List javaServiceProviders, IURLParser urlParser) { + public ViewRepresentationDescriptionsProvider(IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService, List javaServiceProviders, IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate) { this.viewRepresentationDescriptionSearchService = Objects.requireNonNull(viewRepresentationDescriptionSearchService); this.javaServiceProviders = Objects.requireNonNull(javaServiceProviders); - this.urlParser = Objects.requireNonNull(urlParser); + this.viewRepresentationDescriptionPredicate = Objects.requireNonNull(viewRepresentationDescriptionPredicate); } @Override public boolean canHandle(IRepresentationDescription representationDescription) { - if (representationDescription.getId().startsWith(IDiagramIdProvider.DIAGRAM_DESCRIPTION_KIND)) { - Map> parameters = this.urlParser.getParameterValues(representationDescription.getId()); - List values = Optional.ofNullable(parameters.get(IDiagramIdProvider.SOURCE_KIND)).orElse(List.of()); - return values.contains(IDiagramIdProvider.VIEW_SOURCE_KIND); - } - return false; + return this.viewRepresentationDescriptionPredicate.test(representationDescription); } @Override diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ConnectorToolsProviderDiagram.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ConnectorToolsProviderDiagram.java index d579a4e64c..67ac9de192 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ConnectorToolsProviderDiagram.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ConnectorToolsProviderDiagram.java @@ -13,7 +13,6 @@ package org.eclipse.sirius.components.view.emf.diagram; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -21,7 +20,6 @@ import org.eclipse.sirius.components.collaborative.diagrams.api.IConnectorToolsProvider; import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramDescriptionService; import org.eclipse.sirius.components.core.api.IEditingContext; -import org.eclipse.sirius.components.core.api.IURLParser; import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService; import org.eclipse.sirius.components.diagrams.Diagram; import org.eclipse.sirius.components.diagrams.Edge; @@ -30,6 +28,7 @@ import org.eclipse.sirius.components.diagrams.tools.ITool; import org.eclipse.sirius.components.diagrams.tools.SingleClickOnTwoDiagramElementsCandidate; import org.eclipse.sirius.components.diagrams.tools.SingleClickOnTwoDiagramElementsTool; +import org.eclipse.sirius.components.view.emf.IViewRepresentationDescriptionPredicate; import org.springframework.stereotype.Service; /** @@ -44,35 +43,29 @@ public class ConnectorToolsProviderDiagram implements IConnectorToolsProvider { private final IDiagramDescriptionService diagramDescriptionService; - private final IURLParser urlParser; + private final IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate; - public ConnectorToolsProviderDiagram(IRepresentationDescriptionSearchService representationDescriptionSearchService, IDiagramDescriptionService diagramDescriptionService, IURLParser urlParser) { + public ConnectorToolsProviderDiagram(IRepresentationDescriptionSearchService representationDescriptionSearchService, IDiagramDescriptionService diagramDescriptionService, IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate) { this.representationDescriptionSearchService = representationDescriptionSearchService; this.diagramDescriptionService = diagramDescriptionService; - this.urlParser = Objects.requireNonNull(urlParser); + this.viewRepresentationDescriptionPredicate = Objects.requireNonNull(viewRepresentationDescriptionPredicate); } @Override public boolean canHandle(DiagramDescription diagramDescription) { - if (diagramDescription.getId().startsWith(IDiagramIdProvider.DIAGRAM_DESCRIPTION_KIND)) { - Map> parameters = this.urlParser.getParameterValues(diagramDescription.getId()); - List values = Optional.ofNullable(parameters.get(IDiagramIdProvider.SOURCE_KIND)).orElse(List.of()); - return values.contains(IDiagramIdProvider.VIEW_SOURCE_KIND); - } - return false; + return this.viewRepresentationDescriptionPredicate.test(diagramDescription); } @Override public List getConnectorTools(Object sourceDiagramElement, Object targetDiagramElement, Diagram diagram, IEditingContext editingContext) { - var optDiagramDescription = this.representationDescriptionSearchService.findById(editingContext, diagram.getDescriptionId()); var optSourceDiagramElementDescriptionId = this.mapDiagramElementToDescriptionId(sourceDiagramElement); var optTargetDiagramElementDescriptionId = this.mapDiagramElementToDescriptionId(targetDiagramElement); boolean diagramElementDescriptionsPresent = optDiagramDescription.isPresent() && optSourceDiagramElementDescriptionId.isPresent() && optTargetDiagramElementDescriptionId.isPresent(); + List result = null; if (diagramElementDescriptionsPresent && optDiagramDescription.get() instanceof DiagramDescription) { - DiagramDescription diagramDescription = (DiagramDescription) optDiagramDescription.get(); var optSourceDiagramElementDescription = this.mapDescriptionIdToDescription(optSourceDiagramElementDescriptionId.get(), diagramDescription, sourceDiagramElement); var optTargetDiagramElementDescription = this.mapDescriptionIdToDescription(optTargetDiagramElementDescriptionId.get(), diagramDescription, targetDiagramElement); @@ -80,12 +73,12 @@ public List getConnectorTools(Object sourceDiagramElement, Object targetD if (optSourceDiagramElementDescription.isPresent() && optTargetDiagramElementDescription.isPresent()) { Object sourceDescription = optSourceDiagramElementDescription.get(); Object targetDescription = optTargetDiagramElementDescription.get(); - result = diagramDescription.getToolSections().stream().flatMap(ts -> ts.getTools().stream())// - .filter(t -> t instanceof SingleClickOnTwoDiagramElementsTool)// - .map(SingleClickOnTwoDiagramElementsTool.class::cast)// + result = diagramDescription.getToolSections().stream().flatMap(toolSection -> toolSection.getTools().stream()) + .filter(SingleClickOnTwoDiagramElementsTool.class::isInstance) + .map(SingleClickOnTwoDiagramElementsTool.class::cast) .filter(tool -> { List candidates = tool.getCandidates(); - return candidates.stream().anyMatch(c -> c.getSources().contains(sourceDescription) && c.getTargets().contains(targetDescription)); + return candidates.stream().anyMatch(candidate -> candidate.getSources().contains(sourceDescription) && candidate.getTargets().contains(targetDescription)); }).collect(Collectors.toList()); } } @@ -94,10 +87,10 @@ public List getConnectorTools(Object sourceDiagramElement, Object targetD private Optional mapDiagramElementToDescriptionId(Object object) { Optional descriptionId = Optional.empty(); - if (object instanceof Node) { - descriptionId = Optional.of(((Node) object).getDescriptionId()); - } else if (object instanceof Edge) { - descriptionId = Optional.of(((Edge) object).getDescriptionId()); + if (object instanceof Node node) { + descriptionId = Optional.of(node.getDescriptionId()); + } else if (object instanceof Edge edge) { + descriptionId = Optional.of(edge.getDescriptionId()); } return descriptionId; } diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/DiagramIdProvider.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/DiagramIdProvider.java index 40d19593c4..93e05a3822 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/DiagramIdProvider.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/DiagramIdProvider.java @@ -40,7 +40,7 @@ public DiagramIdProvider(IObjectService objectService) { public String getId(DiagramDescription diagramDescription) { String sourceId = this.getSourceIdFromElementDescription(diagramDescription); String sourceElementId = this.objectService.getId(diagramDescription); - return DIAGRAM_DESCRIPTION_KIND + "?" + SOURCE_KIND + "=" + VIEW_SOURCE_KIND + "&" + SOURCE_ID + "=" + sourceId + "&" + SOURCE_ELEMENT_ID + "=" + sourceElementId; + return DIAGRAM_DESCRIPTION_KIND + "&" + SOURCE_KIND + "=" + VIEW_SOURCE_KIND + "&" + SOURCE_ID + "=" + sourceId + "&" + SOURCE_ELEMENT_ID + "=" + sourceElementId; } @Override diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/IDiagramIdProvider.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/IDiagramIdProvider.java index c60400ed84..66c20a7448 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/IDiagramIdProvider.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/IDiagramIdProvider.java @@ -15,28 +15,22 @@ import org.eclipse.sirius.components.view.DiagramDescription; import org.eclipse.sirius.components.view.DiagramElementDescription; +import org.eclipse.sirius.components.view.emf.IRepresentationDescriptionIdProvider; /** * Interface to provide ids for DiagramDescription & DiagramElementDescription. * * @author mcharfadi */ -public interface IDiagramIdProvider { +public interface IDiagramIdProvider extends IRepresentationDescriptionIdProvider { - String DIAGRAM_DESCRIPTION_KIND = "siriusComponents://diagramDescription"; + String DIAGRAM_DESCRIPTION_KIND = PREFIX + "?kind=diagramDescription"; String NODE_DESCRIPTION_KIND = "siriusComponents://nodeDescription"; String EDGE_DESCRIPTION_KIND = "siriusComponents://edgeDescription"; - String SOURCE_KIND = "sourceKind"; - - String SOURCE_ID = "sourceId"; - - String SOURCE_ELEMENT_ID = "sourceElementId"; - - String VIEW_SOURCE_KIND = "view"; - + @Override String getId(DiagramDescription diagramDescription); String getId(DiagramElementDescription diagramElementDescription); diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewDiagramDescriptionConverter.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewDiagramDescriptionConverter.java index 452ebc73d1..cc1a298bf4 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewDiagramDescriptionConverter.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewDiagramDescriptionConverter.java @@ -89,6 +89,10 @@ public class ViewDiagramDescriptionConverter implements IRepresentationDescripti private final IEditService editService; + private final IDiagramIdProvider diagramIdProvider; + + private final IViewToolImageProvider viewToolImageProvider; + private final StylesFactory stylesFactory; private final Function semanticTargetIdProvider; @@ -97,19 +101,15 @@ public class ViewDiagramDescriptionConverter implements IRepresentationDescripti private final Function semanticTargetLabelProvider; - private final IDiagramIdProvider diagramIdProvider; - - private final IViewToolImageProvider viewToolImageProvider; - public ViewDiagramDescriptionConverter(IObjectService objectService, IEditService editService, List iNodeStyleProviders, IDiagramIdProvider diagramIdProvider, IViewToolImageProvider viewToolImageProvider) { this.objectService = Objects.requireNonNull(objectService); this.editService = Objects.requireNonNull(editService); + this.diagramIdProvider = Objects.requireNonNull(diagramIdProvider); + this.viewToolImageProvider = Objects.requireNonNull(viewToolImageProvider); this.stylesFactory = new StylesFactory(Objects.requireNonNull(iNodeStyleProviders), this.objectService); this.semanticTargetIdProvider = variableManager -> this.self(variableManager).map(this.objectService::getId).orElse(null); this.semanticTargetKindProvider = variableManager -> this.self(variableManager).map(this.objectService::getKind).orElse(null); this.semanticTargetLabelProvider = variableManager -> this.self(variableManager).map(this.objectService::getLabel).orElse(null); - this.diagramIdProvider = diagramIdProvider; - this.viewToolImageProvider = Objects.requireNonNull(viewToolImageProvider); } @Override diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewReconnectionToolsExecutor.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewReconnectionToolsExecutor.java index afba2833ff..5d5030cd0f 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewReconnectionToolsExecutor.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewReconnectionToolsExecutor.java @@ -21,11 +21,10 @@ import org.eclipse.emf.ecore.EPackage.Registry; import org.eclipse.sirius.components.collaborative.diagrams.api.IReconnectionToolsExecutor; import org.eclipse.sirius.components.collaborative.diagrams.api.ReconnectionToolInterpreterData; -import org.eclipse.sirius.components.compatibility.api.IIdentifierProvider; import org.eclipse.sirius.components.core.api.IEditService; import org.eclipse.sirius.components.core.api.IEditingContext; -import org.eclipse.sirius.components.core.api.IURLParser; import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.core.api.IURLParser; import org.eclipse.sirius.components.diagrams.Edge; import org.eclipse.sirius.components.diagrams.description.DiagramDescription; import org.eclipse.sirius.components.diagrams.description.EdgeDescription; @@ -38,6 +37,7 @@ import org.eclipse.sirius.components.representations.VariableManager; import org.eclipse.sirius.components.view.View; import org.eclipse.sirius.components.view.emf.IJavaServiceProvider; +import org.eclipse.sirius.components.view.emf.IViewRepresentationDescriptionPredicate; import org.eclipse.sirius.components.view.emf.IViewRepresentationDescriptionSearchService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,30 +62,29 @@ public class ViewReconnectionToolsExecutor implements IReconnectionToolsExecutor private final List javaServiceProviders; - private final ApplicationContext applicationContext; + private final IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate; private final IURLParser urlParser; + private final ApplicationContext applicationContext; + private final Logger logger = LoggerFactory.getLogger(ViewReconnectionToolsExecutor.class); - public ViewReconnectionToolsExecutor(IObjectService objectService, IEditService editService, IIdentifierProvider identifierProvider, - IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService, List javaServiceProviders, ApplicationContext applicationContext, IURLParser urlParser) { + public ViewReconnectionToolsExecutor(IObjectService objectService, IEditService editService, IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService, + List javaServiceProviders, IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate, IURLParser urlParser, + ApplicationContext applicationContext) { this.objectService = Objects.requireNonNull(objectService); this.editService = Objects.requireNonNull(editService); this.viewRepresentationDescriptionSearchService = Objects.requireNonNull(viewRepresentationDescriptionSearchService); this.javaServiceProviders = Objects.requireNonNull(javaServiceProviders); - this.applicationContext = Objects.requireNonNull(applicationContext); + this.viewRepresentationDescriptionPredicate = Objects.requireNonNull(viewRepresentationDescriptionPredicate); this.urlParser = Objects.requireNonNull(urlParser); + this.applicationContext = Objects.requireNonNull(applicationContext); } @Override public boolean canExecute(DiagramDescription diagramDescription) { - if (diagramDescription.getId().startsWith(IDiagramIdProvider.DIAGRAM_DESCRIPTION_KIND)) { - Map> parameters = this.urlParser.getParameterValues(diagramDescription.getId()); - List values = Optional.ofNullable(parameters.get(IDiagramIdProvider.SOURCE_KIND)).orElse(List.of()); - return values.contains(IDiagramIdProvider.VIEW_SOURCE_KIND); - } - return false; + return this.viewRepresentationDescriptionPredicate.test(diagramDescription); } @Override diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewToolSectionsProvider.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewToolSectionsProvider.java index 6964cecbf1..807763a14e 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewToolSectionsProvider.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/ViewToolSectionsProvider.java @@ -14,7 +14,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -30,8 +29,8 @@ import org.eclipse.sirius.components.collaborative.diagrams.dto.SingleClickOnTwoDiagramElementsCandidate; import org.eclipse.sirius.components.collaborative.diagrams.dto.SingleClickOnTwoDiagramElementsTool; import org.eclipse.sirius.components.collaborative.diagrams.dto.ToolSection; -import org.eclipse.sirius.components.core.api.IURLParser; import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.core.api.IURLParser; import org.eclipse.sirius.components.diagrams.Diagram; import org.eclipse.sirius.components.diagrams.Edge; import org.eclipse.sirius.components.diagrams.Node; @@ -44,6 +43,7 @@ import org.eclipse.sirius.components.view.DiagramElementDescription; import org.eclipse.sirius.components.view.EdgeTool; import org.eclipse.sirius.components.view.NodeTool; +import org.eclipse.sirius.components.view.emf.IViewRepresentationDescriptionPredicate; import org.eclipse.sirius.components.view.emf.IViewRepresentationDescriptionSearchService; import org.springframework.stereotype.Service; @@ -66,9 +66,10 @@ @Service public class ViewToolSectionsProvider implements IToolSectionsProvider { - private final IURLParser urlParser; + private final IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate; + private final IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService; private final IDiagramDescriptionService diagramDescriptionService; @@ -79,8 +80,9 @@ public class ViewToolSectionsProvider implements IToolSectionsProvider { return UUID.nameUUIDFromBytes(EcoreUtil.getURI(eObject).toString().getBytes()); }; - public ViewToolSectionsProvider(IURLParser urlParser, IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService, IDiagramDescriptionService diagramDescriptionService, IObjectService objectService) { + public ViewToolSectionsProvider(IURLParser urlParser, IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate, IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService, IDiagramDescriptionService diagramDescriptionService, IObjectService objectService) { this.urlParser = Objects.requireNonNull(urlParser); + this.viewRepresentationDescriptionPredicate = Objects.requireNonNull(viewRepresentationDescriptionPredicate); this.viewRepresentationDescriptionSearchService = Objects.requireNonNull(viewRepresentationDescriptionSearchService); this.diagramDescriptionService = Objects.requireNonNull(diagramDescriptionService); this.objectService = Objects.requireNonNull(objectService); @@ -88,12 +90,7 @@ public ViewToolSectionsProvider(IURLParser urlParser, IViewRepresentationDescrip @Override public boolean canHandle(DiagramDescription diagramDescription) { - if (diagramDescription.getId().startsWith(IDiagramIdProvider.DIAGRAM_DESCRIPTION_KIND)) { - Map> parameters = this.urlParser.getParameterValues(diagramDescription.getId()); - List values = Optional.ofNullable(parameters.get(IDiagramIdProvider.SOURCE_KIND)).orElse(List.of()); - return values.contains(IDiagramIdProvider.VIEW_SOURCE_KIND); - } - return false; + return this.viewRepresentationDescriptionPredicate.test(diagramDescription); } @Override diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/providers/ViewInitialDirectEditElementLabelProvider.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/providers/ViewInitialDirectEditElementLabelProvider.java index 3efb930ffe..2a98f8dc8b 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/providers/ViewInitialDirectEditElementLabelProvider.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/diagram/providers/ViewInitialDirectEditElementLabelProvider.java @@ -14,7 +14,6 @@ import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; @@ -24,7 +23,6 @@ import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramQueryService; import org.eclipse.sirius.components.collaborative.diagrams.api.IInitialDirectEditElementLabelProvider; import org.eclipse.sirius.components.core.api.IEditingContext; -import org.eclipse.sirius.components.core.api.IURLParser; import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.diagrams.Diagram; import org.eclipse.sirius.components.diagrams.Edge; @@ -43,6 +41,7 @@ import org.eclipse.sirius.components.view.NodePalette; import org.eclipse.sirius.components.view.View; import org.eclipse.sirius.components.view.emf.IJavaServiceProvider; +import org.eclipse.sirius.components.view.emf.IViewRepresentationDescriptionPredicate; import org.eclipse.sirius.components.view.emf.IViewRepresentationDescriptionSearchService; import org.eclipse.sirius.components.view.emf.diagram.IDiagramIdProvider; import org.slf4j.Logger; @@ -62,7 +61,7 @@ public class ViewInitialDirectEditElementLabelProvider implements IInitialDirect private final Logger logger = LoggerFactory.getLogger(ViewInitialDirectEditElementLabelProvider.class); - private final IURLParser urlParser; + private final IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate; private final IDiagramQueryService diagramQueryService; @@ -76,9 +75,9 @@ public class ViewInitialDirectEditElementLabelProvider implements IInitialDirect private final ApplicationContext applicationContext; - public ViewInitialDirectEditElementLabelProvider(IURLParser urlParser, IDiagramQueryService diagramQueryService, IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService, IObjectService objectService, + public ViewInitialDirectEditElementLabelProvider(IViewRepresentationDescriptionPredicate viewRepresentationDescriptionPredicate, IDiagramQueryService diagramQueryService, IViewRepresentationDescriptionSearchService viewRepresentationDescriptionSearchService, IObjectService objectService, List javaServiceProviders, IDiagramIdProvider idProvider, ApplicationContext applicationContext) { - this.urlParser = Objects.requireNonNull(urlParser); + this.viewRepresentationDescriptionPredicate = Objects.requireNonNull(viewRepresentationDescriptionPredicate); this.diagramQueryService = Objects.requireNonNull(diagramQueryService); this.viewRepresentationDescriptionSearchService = Objects.requireNonNull(viewRepresentationDescriptionSearchService); this.objectService = Objects.requireNonNull(objectService); @@ -89,19 +88,16 @@ public ViewInitialDirectEditElementLabelProvider(IURLParser urlParser, IDiagramQ @Override public boolean canHandle(org.eclipse.sirius.components.diagrams.description.DiagramDescription diagramDescription) { - if (diagramDescription.getId().startsWith(IDiagramIdProvider.DIAGRAM_DESCRIPTION_KIND)) { - Map> parameters = this.urlParser.getParameterValues(diagramDescription.getId()); - List values = Optional.ofNullable(parameters.get(IDiagramIdProvider.SOURCE_KIND)).orElse(List.of()); - return values.contains(IDiagramIdProvider.VIEW_SOURCE_KIND); - } - return false; + return this.viewRepresentationDescriptionPredicate.test(diagramDescription); } @Override public String getInitialDirectEditElementLabel(Object diagramElement, String labelId, Diagram diagram, IEditingContext editingContext) { String initialDirectEditElementLabel = ""; String diagramDescriptionId = diagram.getDescriptionId(); - var optionalDiagramDescription = this.viewRepresentationDescriptionSearchService.findById(diagramDescriptionId).filter(DiagramDescription.class::isInstance).map(DiagramDescription.class::cast); + var optionalDiagramDescription = this.viewRepresentationDescriptionSearchService.findById(diagramDescriptionId) + .filter(DiagramDescription.class::isInstance) + .map(DiagramDescription.class::cast); if (optionalDiagramDescription.isPresent()) { DiagramDescription diagramDescription = optionalDiagramDescription.get(); diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/FormIdProvider.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/FormIdProvider.java new file mode 100644 index 0000000000..12d32eafa4 --- /dev/null +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/FormIdProvider.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2023 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.view.emf.form; + +import java.util.Objects; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.view.FormDescription; +import org.springframework.stereotype.Service; + +/** + * Implementation of IFormIdProvider. + * + * @author pcdavid + */ +@Service +@SuppressWarnings("checkstyle:MultipleStringLiterals") +public class FormIdProvider implements IFormIdProvider { + + private final IObjectService objectService; + + public FormIdProvider(IObjectService objectService) { + this.objectService = Objects.requireNonNull(objectService); + } + + @Override + public String getId(FormDescription formDescription) { + String sourceId = this.getSourceIdFromElementDescription(formDescription); + String sourceElementId = this.objectService.getId(formDescription); + return FORM_DESCRIPTION_KIND + "&" + SOURCE_KIND + "=" + VIEW_SOURCE_KIND + "&" + SOURCE_ID + "=" + sourceId + "&" + SOURCE_ELEMENT_ID + "=" + sourceElementId; + } + + private String getSourceIdFromElementDescription(EObject elementDescription) { + return elementDescription.eResource().getURI().toString().split("///")[1]; + } +} diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/IFormIdProvider.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/IFormIdProvider.java new file mode 100644 index 0000000000..8912e803f3 --- /dev/null +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/IFormIdProvider.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2023 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.view.emf.form; + + +import org.eclipse.sirius.components.view.FormDescription; +import org.eclipse.sirius.components.view.emf.IRepresentationDescriptionIdProvider; + +/** + * Interface to provide ids for FormDescription. + * + * @author pcdavid + */ +public interface IFormIdProvider extends IRepresentationDescriptionIdProvider { + + String FORM_DESCRIPTION_KIND = PREFIX + "?kind=formDescription"; + + @Override + String getId(FormDescription formDescription); + + /** + * Implementation which does nothing, used for mocks in unit tests. + * + * @author pcdavid + */ + class NoOp implements IFormIdProvider { + + @Override + public String getId(FormDescription formDescription) { + return ""; + } + } +} + diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverter.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverter.java index 8704ba65fe..b01cfeb247 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverter.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverter.java @@ -57,9 +57,11 @@ public class ViewFormDescriptionConverter implements IRepresentationDescriptionC private final IEditService editService; - public ViewFormDescriptionConverter(IObjectService objectService, IEditService editService) { + private final IFormIdProvider formIdProvider; + public ViewFormDescriptionConverter(IObjectService objectService, IEditService editService, IFormIdProvider formIdProvider) { this.objectService = Objects.requireNonNull(objectService); this.editService = Objects.requireNonNull(editService); + this.formIdProvider = Objects.requireNonNull(formIdProvider); } @Override @@ -80,7 +82,7 @@ public IRepresentationDescription convert(RepresentationDescription representati .map(GroupDescription.class::cast) .toList(); - String descriptionId = this.getDescriptionId(viewFormDescription); + String descriptionId = this.formIdProvider.getId(viewFormDescription); PageDescription pageDescription = PageDescription.newPageDescription(descriptionId + "_page") .idProvider(new GetOrCreateRandomIdProvider()) .labelProvider(variableManager -> this.computeFormLabel(viewFormDescription, variableManager, interpreter)) diff --git a/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicFormsTests.java b/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicFormsTests.java index 2a5233db59..c78801258a 100644 --- a/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicFormsTests.java +++ b/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicFormsTests.java @@ -115,6 +115,7 @@ import org.eclipse.sirius.components.view.View; import org.eclipse.sirius.components.view.ViewFactory; import org.eclipse.sirius.components.view.emf.ViewConverter; +import org.eclipse.sirius.components.view.emf.form.IFormIdProvider; import org.eclipse.sirius.components.view.emf.form.ViewFormDescriptionConverter; import org.junit.jupiter.api.Test; import org.springframework.context.support.StaticApplicationContext; @@ -1277,7 +1278,7 @@ public Optional getObject(IEditingContext editingContext, String objectI IEditService.NoOp editService = new IEditService.NoOp() { }; - ViewFormDescriptionConverter formDescriptionConverter = new ViewFormDescriptionConverter(objectService, editService); + ViewFormDescriptionConverter formDescriptionConverter = new ViewFormDescriptionConverter(objectService, editService, new IFormIdProvider.NoOp()); var viewConverter = new ViewConverter(List.of(), List.of(formDescriptionConverter), new StaticApplicationContext()); List conversionResult = viewConverter.convert(List.of(view), List.of(EcorePackage.eINSTANCE)); assertThat(conversionResult).hasSize(1);