Skip to content

Commit

Permalink
[4375] Add support for impact analysis before tool execution
Browse files Browse the repository at this point in the history
Bug: #4375
Signed-off-by: Florian ROUËNÉ <[email protected]>
  • Loading branch information
frouene committed Jan 16, 2025
1 parent 689cf68 commit be05899
Show file tree
Hide file tree
Showing 55 changed files with 2,115 additions and 859 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

=== Breaking changes

- https://github.com/eclipse-sirius/sirius-web/issues/4375[#4375] [diagram] `ToolVariable` has been moved from `sirius-component-collaborative-diagram` to `sirius-component-collaborative`

=== Dependency update

Expand Down Expand Up @@ -64,6 +65,7 @@ Some log messages have been updated in order to provide more information and mak
The configuration property `sirius.web.graphql.tracing` has also been added to active the tracing mode of the GraphQL API.
It can be activated using `sirius.web.graphql.tracing=true` since it is not enabled by default to not have any impact on the performance of the application.
Some additional log has also been contributed on the frontend in order to view more easily the order and time of the GraphQL requests and responses.
- https://github.com/eclipse-sirius/sirius-web/issues/4375[#4375] [diagram] Add support for a first version of impact analysis before tool execution.


=== Improvements
Expand Down Expand Up @@ -220,7 +222,7 @@ These components could be reused by downstream applications in custom creation t
- https://github.com/eclipse-sirius/sirius-web/issues/4330[#4330] [diagram] Improve responsiveness when executing a tool from the palette
- https://github.com/eclipse-sirius/sirius-web/issues/4333[#4333] [diagram] Improve the style of the palette by switching the positions of the search field and the quick access tools and by adding a small touch of grey in the header bar and search field
- https://github.com/eclipse-sirius/sirius-web/issues/4286[#4286] [sirius-web] Make default explorer drag and drop work only for the default explorer.
Downstream applications with a custom explorer that relies on `ExplorerDropTreeItemHandler` now need to provide their own `IDropTreeItemHandler` to support drag and drop in their explorer.
Downstream applications with a custom explorer that relies on `ExplorerDropTreeItemHandler` now need to provide their own `IDropTreeItemHandler` to support drag and drop in their explorer.


== v2024.11.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2022, 2024 Obeo.
* Copyright (c) 2022, 2025 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
Expand Down Expand Up @@ -79,6 +79,7 @@ public CompatibilityPaletteProvider(IIdentifierProvider identifierProvider, IODe
this.odesignRegistry = Objects.requireNonNull(odesignRegistry);
this.interpreterFactory = Objects.requireNonNull(interpreterFactory);
}

@Override
public boolean canHandle(DiagramDescription diagramDescription) {
return this.identifierProvider.findVsmElementId(diagramDescription.getId()).isPresent();
Expand Down Expand Up @@ -136,7 +137,7 @@ private ITool convertTool(org.eclipse.sirius.components.diagrams.tools.ITool too
if (tool instanceof org.eclipse.sirius.components.diagrams.tools.SingleClickOnDiagramElementTool singleClickOnDiagramElementTool) {
convertedTool = new SingleClickOnDiagramElementTool(singleClickOnDiagramElementTool.getId(), singleClickOnDiagramElementTool.getLabel(),
singleClickOnDiagramElementTool.getIconURL(), singleClickOnDiagramElementTool.getTargetDescriptions(),
singleClickOnDiagramElementTool.getDialogDescriptionId(), singleClickOnDiagramElementTool.isAppliesToDiagramRoot());
singleClickOnDiagramElementTool.getDialogDescriptionId(), singleClickOnDiagramElementTool.isAppliesToDiagramRoot(), singleClickOnDiagramElementTool.isWithImpactAnalysis());
}
if (tool instanceof org.eclipse.sirius.components.diagrams.tools.SingleClickOnTwoDiagramElementsTool singleClickOnTwoDiagramElementsTool) {
List<SingleClickOnTwoDiagramElementsCandidate> candidates = new ArrayList<>();
Expand Down Expand Up @@ -302,26 +303,26 @@ private List<ToolSection> createExtraToolSections(Object diagramElementDescripti
} else {
targetDescriptions.addAll(edgeDescription.getSourceNodeDescriptions());
}
unsynchronizedMapping = SynchronizationPolicy.UNSYNCHRONIZED.equals(((EdgeDescription) diagramElementDescription).getSynchronizationPolicy());
unsynchronizedMapping = SynchronizationPolicy.UNSYNCHRONIZED.equals(edgeDescription.getSynchronizationPolicy());
}

// Graphical Delete Tool for unsynchronized mapping only (the handler is never called)
if (diagramElementDescription instanceof NodeDescription || diagramElementDescription instanceof EdgeDescription) {
// Edit Tool (the handler is never called)
SingleClickOnDiagramElementTool editTool = new SingleClickOnDiagramElementTool("edit", "Edit", List.of(DiagramImageConstants.EDIT_SVG), targetDescriptions, null, false);
SingleClickOnDiagramElementTool editTool = new SingleClickOnDiagramElementTool("edit", "Edit", List.of(DiagramImageConstants.EDIT_SVG), targetDescriptions, null, false, false);
var editToolSection = new ToolSection("edit-section", "", List.of(), List.of(editTool));
extraToolSections.add(editToolSection);

if (unsynchronizedMapping) {
SingleClickOnDiagramElementTool graphicalDeleteTool = new SingleClickOnDiagramElementTool("graphical-delete", "Delete from diagram",
List.of(DiagramImageConstants.GRAPHICAL_DELETE_SVG), targetDescriptions, null, false);
List.of(DiagramImageConstants.GRAPHICAL_DELETE_SVG), targetDescriptions, null, false, false);
var graphicalDeleteToolSection = new ToolSection("graphical-delete-section", "", List.of(), List.of(graphicalDeleteTool));
extraToolSections.add(graphicalDeleteToolSection);
}

// Semantic Delete Tool (the handler is never called)
SingleClickOnDiagramElementTool semanticDeleteTool = new SingleClickOnDiagramElementTool("semantic-delete", "Delete from model",
List.of(DiagramImageConstants.SEMANTIC_DELETE_SVG), targetDescriptions, null, false);
List.of(DiagramImageConstants.SEMANTIC_DELETE_SVG), targetDescriptions, null, false, false);
var graphicalDeleteToolSection = new ToolSection("semantic-delete-section", "", List.of(), List.of(semanticDeleteTool));
extraToolSections.add(graphicalDeleteToolSection);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021, 2024 Obeo.
* Copyright (c) 2021, 2025 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
Expand All @@ -24,6 +24,9 @@
* @author sbegaudeau
*/
public interface IRepresentationSearchService {

Optional<IRepresentation> findById(IEditingContext editingContext, String representationId);

<T extends IRepresentation> Optional<T> findById(IEditingContext editingContext, String representationId, Class<T> representationClass);

boolean existByIdAndKind(String representationId, List<String> kinds);
Expand All @@ -35,6 +38,11 @@ public interface IRepresentationSearchService {
*/
class NoOp implements IRepresentationSearchService {

@Override
public Optional<IRepresentation> findById(IEditingContext editingContext, String representationId) {
return Optional.empty();
}

@Override
public <T extends IRepresentation> Optional<T> findById(IEditingContext editingContext, String representationId, Class<T> representationClass) {
return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2025 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.collaborative.api;

import java.util.List;

import org.eclipse.sirius.components.collaborative.dto.ToolVariable;
import org.eclipse.sirius.components.core.api.IEditingContext;
import org.eclipse.sirius.components.representations.IRepresentation;
import org.eclipse.sirius.components.representations.IStatus;

/**
* Used to execute a tool on a representation.
*
* @author frouene
*/
public interface IToolRepresentationExecutor {

boolean canExecute(IEditingContext editingContext, IRepresentation representation);

IStatus execute(IEditingContext editingContext, IRepresentation representation, String toolId, String targetObjectId, List<ToolVariable> variables);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2025 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.collaborative.dto;

import java.util.List;

/**
* Report with data to display on an impact analysis.
*
* @author frouene
*/
public record ImpactAnalysisReport(int nbElementDeleted, int nbElementModified, int nbElementCreated, List<String> additionalReports) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2025 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.collaborative.dto;

import java.util.List;
import java.util.UUID;

import org.eclipse.sirius.components.core.api.IInput;

/**
* The input for the "impact analysis" query.
*
* @author frouene
*/
public record InvokeImpactAnalysisToolInput(UUID id, String editingContextId, String representationId, String toolId, String targetObjectId, List<ToolVariable> variables) implements IInput {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2022, 2025 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.collaborative.dto;

import java.util.List;
import java.util.Objects;
import java.util.UUID;

import org.eclipse.sirius.components.core.api.IPayload;
import org.eclipse.sirius.components.representations.Message;

/**
* The "initial direct edit element label" success payload.
*
* @author gcoutable
*/
public record InvokeImpactAnalysisToolSuccessPayload(UUID id, ImpactAnalysisReport impactAnalysisReport, List<Message> messages) implements IPayload {

public InvokeImpactAnalysisToolSuccessPayload {
Objects.requireNonNull(id);
Objects.requireNonNull(impactAnalysisReport);
Objects.requireNonNull(messages);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* Copyright (c) 2024, 2025 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
Expand All @@ -10,7 +10,7 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.components.collaborative.diagrams.dto;
package org.eclipse.sirius.components.collaborative.dto;

/**
* Represents a ToolVariable entry.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* Copyright (c) 2024, 2025 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
Expand All @@ -10,7 +10,7 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.components.collaborative.diagrams.dto;
package org.eclipse.sirius.components.collaborative.dto;

/**
* Represent the Type of the Tool Variable.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
extend type RepresentationMetadata {
impactAnalysisReport(toolId: ID!, targetObjectId: ID!, variables: [ToolVariable!]!): ImpactAnalysisReport!
}

type ImpactAnalysisReport {
nbElementDeleted: Int!
nbElementModified: Int!
nbElementCreated: Int!
additionalReports: [String!]!
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*******************************************************************************
* Copyright (c) 2025 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.core.graphql.datafetchers;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

import org.eclipse.sirius.components.annotations.spring.graphql.QueryDataFetcher;
import org.eclipse.sirius.components.collaborative.dto.ImpactAnalysisReport;
import org.eclipse.sirius.components.collaborative.dto.InvokeImpactAnalysisToolInput;
import org.eclipse.sirius.components.collaborative.dto.InvokeImpactAnalysisToolSuccessPayload;
import org.eclipse.sirius.components.collaborative.dto.ToolVariable;
import org.eclipse.sirius.components.graphql.api.IDataFetcherWithFieldCoordinates;
import org.eclipse.sirius.components.graphql.api.IEditingContextDispatcher;
import org.eclipse.sirius.components.graphql.api.LocalContextConstants;

import graphql.schema.DataFetchingEnvironment;
import reactor.core.publisher.Mono;

/**
* Used to retrieve the impact analysis on a tool execution.
*
* @author frouene
*/
@QueryDataFetcher(type = "RepresentationMetadata", field = "impactAnalysisReport")
public class ImpactAnalysisReportDataFetcher implements IDataFetcherWithFieldCoordinates<CompletableFuture<ImpactAnalysisReport>> {

private static final String TOOL_ID = "toolId";
private static final String TARGET_OBJECT_ID = "targetObjectId";

private static final String VARIABLES = "variables";

private final ObjectMapper objectMapper;

private final IEditingContextDispatcher editingContextDispatcher;

public ImpactAnalysisReportDataFetcher(ObjectMapper objectMapper, IEditingContextDispatcher editingContextDispatcher) {
this.objectMapper = Objects.requireNonNull(objectMapper);
this.editingContextDispatcher = Objects.requireNonNull(editingContextDispatcher);
}

@Override
public CompletableFuture<ImpactAnalysisReport> get(DataFetchingEnvironment environment) throws Exception {
CompletableFuture<ImpactAnalysisReport> result = Mono.<ImpactAnalysisReport>empty().toFuture();
Map<String, Object> localContext = environment.getLocalContext();

String editingContextId = Optional.ofNullable(localContext.get(LocalContextConstants.EDITING_CONTEXT_ID)).map(Object::toString).orElse(null);
String representationId = Optional.ofNullable(localContext.get(LocalContextConstants.REPRESENTATION_ID)).map(Object::toString).orElse(null);
String toolId = environment.getArgument(TOOL_ID);
String targetObjectId = environment.getArgument(TARGET_OBJECT_ID);
var variables = Optional.ofNullable(environment.getArgument(VARIABLES))
.filter(List.class::isInstance)
.map(List.class::cast)
.map(this::convertToToolVariables)
.orElseGet(List::of);
if (editingContextId != null && representationId != null) {
InvokeImpactAnalysisToolInput input = new InvokeImpactAnalysisToolInput(UUID.randomUUID(), editingContextId, representationId, toolId, targetObjectId, variables);
result = this.editingContextDispatcher.dispatchQuery(input.editingContextId(), input)
.filter(InvokeImpactAnalysisToolSuccessPayload.class::isInstance)
.map(InvokeImpactAnalysisToolSuccessPayload.class::cast)
.map(InvokeImpactAnalysisToolSuccessPayload::impactAnalysisReport)
.toFuture();
}
return result;
}

private List<ToolVariable> convertToToolVariables(List<?> arguments) {
return arguments.stream()
.map(argument -> this.objectMapper.convertValue(argument, ToolVariable.class))
.toList();
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2023, 2024 Obeo.
* Copyright (c) 2023, 2025 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
Expand Down Expand Up @@ -27,3 +27,11 @@ export interface GQLSuccessPayload {
id: string | null;
messages: GQLMessage[] | null;
}

export interface GQLToolVariable {
name: string;
value: string;
type: GQLToolVariableType;
}

export type GQLToolVariableType = 'STRING' | 'OBJECT_ID' | 'OBJECT_ID_ARRAY';
6 changes: 5 additions & 1 deletion packages/core/frontend/sirius-components-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2022, 2024 Obeo and others.
* Copyright (c) 2022, 2025 Obeo and others.
* 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
Expand Down Expand Up @@ -45,6 +45,10 @@ export * from './modals/confirmation/ConfirmationDialogContext';
export type * from './modals/confirmation/ConfirmationDialogContext.types';
export * from './modals/confirmation/useConfirmationDialog';
export type * from './modals/confirmation/useConfirmationDialog.types';
export * from './modals/impact-analysis/ImpactAnalysisDialogContext';
export type * from './modals/impact-analysis/ImpactAnalysisDialogContext.types';
export * from './modals/impact-analysis/useImpactAnalysisDialog';
export type * from './modals/impact-analysis/useImpactAnalysisDialog.types';
export * from './modals/share-representation/ShareRepresentationModal';
export type * from './modals/share-representation/ShareRepresentationModal.types';
export * from './representationmetadata/useRepresentationMetadata';
Expand Down
Loading

0 comments on commit be05899

Please sign in to comment.