Skip to content

Commit f08ff90

Browse files
committed
[6047] Perform the refresh of the hierarchy representation outside of its event processor
Bug: #6047 Signed-off-by: Stéphane Bégaudeau <stephane.begaudeau@obeo.fr>
1 parent b46b683 commit f08ff90

File tree

17 files changed

+419
-198
lines changed

17 files changed

+419
-198
lines changed

CHANGELOG.adoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ Other representations will follow the same patterns.
186186
Those new APIs and constants are still subject to various changes but once the API will be stable, existing variables will be marked as deprecated.
187187
New variables will only be available thanks to the new API such as `DiagramVariables.SELECTED_NODES` or `DiagramVariables.SELECTED_EDGES` for group tools.
188188
The current constants and the new ones can be mixed without issues.
189+
- https://github.com/eclipse-sirius/sirius-web/issues/6047[#6047] [core] The method `IRepresentationEventProcessor#refresh` will be removed and it will be replaced by dedicated stateless services implementing `IRepresentationRefresher`
189190

190191

191192
=== Breaking changes
@@ -307,6 +308,9 @@ The workbench view ID is now `related-views`.
307308
`PublishLibrariesInput#projectId` has been replaced with `PublishLibrariesInput#editingContextId`.
308309
Note that the namespace of published libraries from studios still matches the `projectId` of the published studio.
309310
- [sirius-web] The method signature of `IRepresentationContentMigrationService#getMigratedContent` has been modified to take individual parameters (`String representationContent, String kind, String lastMigrationPerformed, String migrationVersion`) instead of domain objects (`RepresentationMetadata representationMetadata, RepresentationContent representationContent`).
311+
- https://github.com/eclipse-sirius/sirius-web/issues/6047[#6047] [charts] The mutable class `HierarchyContext` has been transformed into an immutable record.
312+
The service `HierarchyCreationService` is now implementing an interface `IHierarchyCreationService` and its two methods `HierarchyCreationService#create` and `HierarchyCreationService#render` have been merged into a single method with a new signature `IHierarchyCreationService#create`.
313+
This will be used as an inspiration for the evolution of other similar services like `DiagramCreationService`.
310314

311315

312316
=== Dependency update
@@ -444,6 +448,11 @@ The only difference is that this new marker has a second range of two dots after
444448
Downstream applications can now implement `IUndoRedoIgnoreInputPredicate` to ignore additional inputs from the `UndoRedoRecorder`.
445449
- https://github.com/eclipse-sirius/sirius-web/issues/6027[#6027] [diagram] Improve visual feedback when dragging a node to show which targets are compatible/valid/invalid for a drop
446450
- https://github.com/eclipse-sirius/sirius-web/issues/6113[#6113] [core] Allow the customization of the workbench configuration
451+
- https://github.com/eclipse-sirius/sirius-web/issues/6032[#6032] [diagram] Ensure edge handles on border nodes are placed opposite their anchor point
452+
- https://github.com/eclipse-sirius/sirius-web/issues/6047[#6047] [charts] Perform the refresh of the hierarchy representation outside of its representation event processor.
453+
To perform the refresh of the representation event processor, an instance of `IRepresentationRefresher` will be required.
454+
A new method `IHierarchyEventProcessor#updateState` is available to update the state of the hierarchy event processor and publish a new hierarchy to the subscribers.
455+
447456

448457

449458
== 2025.12.0

packages/charts/backend/sirius-components-collaborative-charts/src/main/java/org/eclipse/sirius/components/collaborative/charts/CreateHierarchyEventHandler.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2022, 2025 Obeo.
2+
* Copyright (c) 2022, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -24,6 +24,7 @@
2424
import org.eclipse.sirius.components.collaborative.api.IRepresentationMetadataPersistenceService;
2525
import org.eclipse.sirius.components.collaborative.api.IRepresentationPersistenceService;
2626
import org.eclipse.sirius.components.collaborative.api.Monitoring;
27+
import org.eclipse.sirius.components.collaborative.charts.api.IHierarchyCreationService;
2728
import org.eclipse.sirius.components.collaborative.charts.messages.ICollaborativeChartsMessageService;
2829
import org.eclipse.sirius.components.collaborative.dto.CreateRepresentationInput;
2930
import org.eclipse.sirius.components.collaborative.dto.CreateRepresentationSuccessPayload;
@@ -60,13 +61,13 @@ public class CreateHierarchyEventHandler implements IEditingContextEventHandler
6061

6162
private final ICollaborativeChartsMessageService messageService;
6263

63-
private final HierarchyCreationService hierarchyCreationService;
64+
private final IHierarchyCreationService hierarchyCreationService;
6465

6566
private final Counter counter;
6667

6768
public CreateHierarchyEventHandler(IRepresentationDescriptionSearchService representationDescriptionSearchService, IRepresentationMetadataPersistenceService representationMetadataPersistenceService,
6869
IRepresentationPersistenceService representationPersistenceService, IObjectSearchService objectSearchService, ICollaborativeChartsMessageService messageService,
69-
HierarchyCreationService hierarchyCreationService, MeterRegistry meterRegistry) {
70+
IHierarchyCreationService hierarchyCreationService, MeterRegistry meterRegistry) {
7071
this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService);
7172
this.representationPersistenceService = Objects.requireNonNull(representationPersistenceService);
7273
this.representationMetadataPersistenceService = Objects.requireNonNull(representationMetadataPersistenceService);
@@ -114,7 +115,7 @@ public void handle(One<IPayload> payloadSink, Many<ChangeDescription> changeDesc
114115
String label = representationDescription.getLabelProvider().apply(variableManager);
115116
List<String> iconURLs = representationDescription.getIconURLsProvider().apply(variableManager);
116117

117-
Hierarchy hierarchy = this.hierarchyCreationService.create(object, representationDescription, editingContext);
118+
Hierarchy hierarchy = this.hierarchyCreationService.create(editingContext, representationDescription, object, null);
118119
var representationMetadata = RepresentationMetadata.newRepresentationMetadata(hierarchy.getId())
119120
.kind(hierarchy.getKind())
120121
.label(label)
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2022, 2023 Obeo.
2+
* Copyright (c) 2022, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -21,19 +21,8 @@
2121
*
2222
* @author sbegaudeau
2323
*/
24-
public class HierarchyContext {
25-
26-
private Hierarchy hierarchy;
27-
28-
public HierarchyContext(Hierarchy hierarchy) {
29-
this.hierarchy = Objects.requireNonNull(hierarchy);
30-
}
31-
32-
public Hierarchy getHierarchy() {
33-
return this.hierarchy;
34-
}
35-
36-
public void update(Hierarchy newHierarchy) {
37-
this.hierarchy = newHierarchy;
24+
public record HierarchyContext(Hierarchy hierarchy) {
25+
public HierarchyContext {
26+
Objects.requireNonNull(hierarchy);
3827
}
3928
}

packages/charts/backend/sirius-components-collaborative-charts/src/main/java/org/eclipse/sirius/components/collaborative/charts/HierarchyCreationService.java

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2022, 2025 Obeo.
2+
* Copyright (c) 2022, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -12,7 +12,6 @@
1212
*******************************************************************************/
1313
package org.eclipse.sirius.components.collaborative.charts;
1414

15-
import java.util.Objects;
1615
import java.util.Optional;
1716
import java.util.concurrent.TimeUnit;
1817

@@ -22,9 +21,8 @@
2221
import org.eclipse.sirius.components.charts.hierarchy.descriptions.HierarchyDescription;
2322
import org.eclipse.sirius.components.charts.hierarchy.renderer.HierarchyRenderer;
2423
import org.eclipse.sirius.components.collaborative.api.Monitoring;
24+
import org.eclipse.sirius.components.collaborative.charts.api.IHierarchyCreationService;
2525
import org.eclipse.sirius.components.core.api.IEditingContext;
26-
import org.eclipse.sirius.components.core.api.IObjectSearchService;
27-
import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService;
2826
import org.eclipse.sirius.components.representations.Element;
2927
import org.eclipse.sirius.components.representations.VariableManager;
3028
import org.springframework.stereotype.Service;
@@ -38,50 +36,25 @@
3836
* @author sbegaudeau
3937
*/
4038
@Service
41-
public class HierarchyCreationService {
42-
43-
private final IRepresentationDescriptionSearchService representationDescriptionSearchService;
44-
45-
private final IObjectSearchService objectSearchService;
39+
public class HierarchyCreationService implements IHierarchyCreationService {
4640

4741
private final Timer timer;
4842

49-
public HierarchyCreationService(IRepresentationDescriptionSearchService representationDescriptionSearchService, IObjectSearchService objectSearchService, MeterRegistry meterRegistry) {
50-
this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService);
51-
this.objectSearchService = Objects.requireNonNull(objectSearchService);
43+
public HierarchyCreationService(MeterRegistry meterRegistry) {
5244
this.timer = Timer.builder(Monitoring.REPRESENTATION_EVENT_PROCESSOR_REFRESH)
5345
.tag(Monitoring.NAME, "hierarchy")
5446
.register(meterRegistry);
5547
}
5648

57-
public Hierarchy create(Object targetObject, HierarchyDescription hierarchyDescription, IEditingContext editingContext) {
58-
return this.doRender(targetObject, editingContext, hierarchyDescription, Optional.empty());
59-
}
60-
61-
public Optional<Hierarchy> refresh(IEditingContext editingContext, HierarchyContext hierarchyContext) {
62-
Hierarchy previousHierarchy = hierarchyContext.getHierarchy();
63-
var optionalObject = this.objectSearchService.getObject(editingContext, previousHierarchy.getTargetObjectId());
64-
var optionalHierarchyDescription = this.representationDescriptionSearchService.findById(editingContext, previousHierarchy.getDescriptionId())
65-
.filter(HierarchyDescription.class::isInstance)
66-
.map(HierarchyDescription.class::cast);
67-
68-
if (optionalObject.isPresent() && optionalHierarchyDescription.isPresent()) {
69-
Object object = optionalObject.get();
70-
HierarchyDescription hierarchyDescription = optionalHierarchyDescription.get();
71-
Hierarchy hierarchy = this.doRender(object, editingContext, hierarchyDescription, Optional.of(hierarchyContext));
72-
return Optional.of(hierarchy);
73-
}
74-
return Optional.empty();
75-
}
76-
77-
private Hierarchy doRender(Object targetObject, IEditingContext editingContext, HierarchyDescription hierarchyDescription, Optional<HierarchyContext> optionalHierarchyContext) {
49+
@Override
50+
public Hierarchy create(IEditingContext editingContext, HierarchyDescription hierarchyDescription, Object targetObject, HierarchyContext hierarchyContext) {
7851
long start = System.currentTimeMillis();
7952

8053
VariableManager variableManager = new VariableManager();
8154
variableManager.put(VariableManager.SELF, targetObject);
8255
variableManager.put(IEditingContext.EDITING_CONTEXT, editingContext);
8356

84-
Optional<Hierarchy> optionalPreviousHierarchy = optionalHierarchyContext.map(HierarchyContext::getHierarchy);
57+
Optional<Hierarchy> optionalPreviousHierarchy = Optional.ofNullable(hierarchyContext).map(HierarchyContext::hierarchy);
8558

8659
HierarchyComponentProps props = new HierarchyComponentProps(variableManager, hierarchyDescription, optionalPreviousHierarchy);
8760
Element element = new Element(HierarchyComponent.class, props);

packages/charts/backend/sirius-components-collaborative-charts/src/main/java/org/eclipse/sirius/components/collaborative/charts/HierarchyEventProcessor.java

Lines changed: 12 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,10 @@
1313
package org.eclipse.sirius.components.collaborative.charts;
1414

1515
import java.util.Objects;
16-
import java.util.Optional;
1716

1817
import org.eclipse.sirius.components.charts.hierarchy.Hierarchy;
1918
import org.eclipse.sirius.components.collaborative.api.ChangeDescription;
20-
import org.eclipse.sirius.components.collaborative.api.ChangeKind;
21-
import org.eclipse.sirius.components.collaborative.api.IRepresentationPersistenceStrategy;
22-
import org.eclipse.sirius.components.collaborative.api.IRepresentationSearchService;
2319
import org.eclipse.sirius.components.collaborative.api.ISubscriptionManager;
24-
import org.eclipse.sirius.components.core.api.IEditingContext;
2520
import org.eclipse.sirius.components.core.api.IInput;
2621
import org.eclipse.sirius.components.core.api.IPayload;
2722
import org.eclipse.sirius.components.core.api.IRepresentationInput;
@@ -42,45 +37,27 @@ public class HierarchyEventProcessor implements IHierarchyEventProcessor {
4237

4338
private final Logger logger = LoggerFactory.getLogger(HierarchyEventProcessor.class);
4439

45-
private final IEditingContext editingContext;
46-
47-
private final HierarchyContext hierarchyContext;
48-
4940
private final ISubscriptionManager subscriptionManager;
5041

51-
private final HierarchyCreationService hierarchyCreationService;
52-
53-
private final IRepresentationPersistenceStrategy representationPersistenceStrategy;
54-
5542
private final HierarchyEventFlux hierarchyEventFlux;
5643

57-
private final IRepresentationSearchService representationSearchService;
58-
59-
public HierarchyEventProcessor(IEditingContext editingContext, HierarchyContext hierarchyContext, ISubscriptionManager subscriptionManager, HierarchyCreationService hierarchyCreationService,
60-
IRepresentationPersistenceStrategy representationPersistenceStrategy,
61-
IRepresentationSearchService representationSearchService) {
62-
this.logger.trace("Creating the hierarchy event processor {}", hierarchyContext.getHierarchy().getId());
44+
private HierarchyContext hierarchyContext;
6345

64-
this.editingContext = Objects.requireNonNull(editingContext);
46+
public HierarchyEventProcessor(HierarchyContext hierarchyContext, ISubscriptionManager subscriptionManager) {
6547
this.hierarchyContext = Objects.requireNonNull(hierarchyContext);
6648
this.subscriptionManager = Objects.requireNonNull(subscriptionManager);
67-
this.hierarchyCreationService = Objects.requireNonNull(hierarchyCreationService);
68-
this.representationPersistenceStrategy = Objects.requireNonNull(representationPersistenceStrategy);
69-
this.representationSearchService = Objects.requireNonNull(representationSearchService);
70-
71-
// We automatically refresh the representation before using it since things may have changed since the moment it
72-
// has been saved in the database. This is quite similar to the auto-refresh on loading in Sirius.
73-
Hierarchy hierarchy = this.hierarchyCreationService.refresh(editingContext, hierarchyContext).orElse(null);
74-
this.representationPersistenceStrategy.applyPersistenceStrategy(null, editingContext, hierarchy);
75-
hierarchyContext.update(hierarchy);
76-
this.hierarchyEventFlux = new HierarchyEventFlux(hierarchy);
77-
78-
this.logger.trace("Hierarchy refreshed: {})", hierarchy.getId());
49+
this.hierarchyEventFlux = new HierarchyEventFlux(hierarchyContext.hierarchy());
7950
}
8051

8152
@Override
8253
public IRepresentation getRepresentation() {
83-
return this.hierarchyContext.getHierarchy();
54+
return this.hierarchyContext.hierarchy();
55+
}
56+
57+
@Override
58+
public void updateState(IInput input, Hierarchy hierarchy) {
59+
this.hierarchyContext = new HierarchyContext(hierarchy);
60+
this.hierarchyEventFlux.hierarchyRefreshed(input, hierarchy);
8461
}
8562

8663
@Override
@@ -95,32 +72,7 @@ public void handle(One<IPayload> payloadSink, Many<ChangeDescription> changeDesc
9572

9673
@Override
9774
public void refresh(ChangeDescription changeDescription) {
98-
if (this.shouldRefresh(changeDescription)) {
99-
Hierarchy refreshedHierarchy = this.hierarchyCreationService.refresh(this.editingContext, this.hierarchyContext).orElse(null);
100-
this.representationPersistenceStrategy.applyPersistenceStrategy(changeDescription.getInput(), this.editingContext, refreshedHierarchy);
101-
102-
this.logger.trace("Hierarchy refreshed: {}", refreshedHierarchy.getId());
103-
104-
this.hierarchyContext.update(refreshedHierarchy);
105-
this.hierarchyEventFlux.hierarchyRefreshed(changeDescription.getInput(), refreshedHierarchy);
106-
} else if (changeDescription.getKind().equals(ChangeKind.RELOAD_REPRESENTATION) && changeDescription.getSourceId().equals(this.hierarchyContext.getHierarchy().getId())) {
107-
Optional<Hierarchy> reloadedHierarchy = this.representationSearchService.findById(this.editingContext, this.hierarchyContext.getHierarchy().getId(), Hierarchy.class);
108-
if (reloadedHierarchy.isPresent()) {
109-
this.hierarchyContext.update(reloadedHierarchy.get());
110-
this.hierarchyEventFlux.hierarchyRefreshed(changeDescription.getInput(), reloadedHierarchy.get());
111-
}
112-
}
113-
}
114-
115-
/**
116-
* A hierarchy representation is refresh if there is a semantic change.
117-
*
118-
* @param changeDescription
119-
* The change description
120-
* @return <code>true</code> if the representation should be refreshed, <code>false</code> otherwise
121-
*/
122-
private boolean shouldRefresh(ChangeDescription changeDescription) {
123-
return ChangeKind.SEMANTIC_CHANGE.equals(changeDescription.getKind());
75+
// To be removed
12476
}
12577

12678
@Override
@@ -133,7 +85,7 @@ public Flux<IPayload> getOutputEvents(IInput input) {
13385

13486
@Override
13587
public void dispose() {
136-
this.logger.trace("Disposing the hierarchy event processor {}", this.hierarchyContext.getHierarchy().getId());
88+
this.logger.trace("Disposing the hierarchy event processor {}", this.hierarchyContext.hierarchy().getId());
13789

13890
this.subscriptionManager.dispose();
13991
this.hierarchyEventFlux.dispose();

0 commit comments

Comments
 (0)