Skip to content

Commit

Permalink
[3875] PR review changes
Browse files Browse the repository at this point in the history
Bug: eclipse-sirius#3875
Signed-off-by: Jerome Gout <jerome.gout@obeosoft.com>
  • Loading branch information
jerome-obeo committed Aug 28, 2024
1 parent db6350a commit 98578a3
Show file tree
Hide file tree
Showing 32 changed files with 779 additions and 583 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ As a result, the following maven modules have been deleted: `sirius-web-sample-a
- https://github.com/eclipse-sirius/sirius-web/issues/3437[#3437] [core] Migrate frontend to MUI 5, if you contributed React componenent that use MUI, you should upgrade them to use MUI 5.
- https://github.com/eclipse-sirius/sirius-web/issues/2204[#2204] [core] Added `getStyledLabel` in `IDefaultLabelService` and `IObjectService`, you must implement this method if you have custom implementation of these interface.
- https://github.com/eclipse-sirius/sirius-web/issues/3815[#3815] [core] Make child creation descriptions locale independent
- https://github.com/eclipse-sirius/sirius-web/issues/2204[#2204] [core, tree] Added `getStyledLabel` in `IDefaultLabelService` and `IObjectService`, you must implement this method if you have custom implementation of these interface.
- https://github.com/eclipse-sirius/sirius-web/issues/3875[#3875] [sirius-web] `ExplorerView` component has been moved from components-trees to sirius-web-application module

=== Dependency update

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.components.collaborative.widget.reference.browser;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

import org.eclipse.sirius.components.collaborative.api.IRepresentationConfiguration;
import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessor;
import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessorFactory;
import org.eclipse.sirius.components.collaborative.api.IRepresentationRefreshPolicyRegistry;
import org.eclipse.sirius.components.collaborative.api.ISubscriptionManagerFactory;
import org.eclipse.sirius.components.collaborative.trees.TreeEventProcessor;
import org.eclipse.sirius.components.collaborative.trees.api.ITreeEventHandler;
import org.eclipse.sirius.components.collaborative.trees.api.ITreeService;
import org.eclipse.sirius.components.collaborative.trees.api.TreeCreationParameters;
import org.eclipse.sirius.components.collaborative.widget.reference.configurations.ModelBrowserConfiguration;
import org.eclipse.sirius.components.core.api.IEditingContext;
import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService;
import org.eclipse.sirius.components.trees.description.TreeDescription;
import org.springframework.stereotype.Service;

import io.micrometer.core.instrument.simple.SimpleMeterRegistry;

/**
* Used to create the tree event processors in the context of model browser.
*
* @author Jerome Gout
*/
@Service
public class ModelBrowserEventProcessorFactory implements IRepresentationEventProcessorFactory {

private final IRepresentationDescriptionSearchService representationDescriptionSearchService;

private final ITreeService treeService;

private final List<ITreeEventHandler> treeEventHandlers;

private final ISubscriptionManagerFactory subscriptionManagerFactory;

private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry;

public ModelBrowserEventProcessorFactory(IRepresentationDescriptionSearchService representationDescriptionSearchService, List<ITreeEventHandler> treeEventHandlers, ITreeService treeService, IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry, ISubscriptionManagerFactory subscriptionManagerFactory) {
this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService);
this.treeService = Objects.requireNonNull(treeService);
this.treeEventHandlers = Objects.requireNonNull(treeEventHandlers);
this.subscriptionManagerFactory = Objects.requireNonNull(subscriptionManagerFactory);
this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry);
}

@Override
public boolean canHandle(IRepresentationConfiguration configuration) {
return configuration instanceof ModelBrowserConfiguration;
}

@Override
public Optional<IRepresentationEventProcessor> createRepresentationEventProcessor(IRepresentationConfiguration configuration, IEditingContext editingContext) {
if (configuration instanceof ModelBrowserConfiguration modelBrowserConfiguration) {

String descriptionId;
if (modelBrowserConfiguration.getId().startsWith(ModelBrowsersDescriptionProvider.MODEL_BROWSER_CONTAINER_PREFIX)) {
descriptionId = ModelBrowsersDescriptionProvider.CONTAINER_DESCRIPTION_ID;
} else {
descriptionId = ModelBrowsersDescriptionProvider.REFERENCE_DESCRIPTION_ID;
}

Optional<TreeDescription> optionalTreeDescription = this.representationDescriptionSearchService
.findById(editingContext, descriptionId)
.filter(TreeDescription.class::isInstance)
.map(TreeDescription.class::cast);
if (optionalTreeDescription.isPresent()) {
var treeDescription = optionalTreeDescription.get();

TreeCreationParameters treeCreationParameters = TreeCreationParameters.newTreeCreationParameters(modelBrowserConfiguration.getId())
.treeDescription(treeDescription)
.activeFilterIds(List.of())
.expanded(modelBrowserConfiguration.getExpanded())
.editingContext(editingContext)
.build();

IRepresentationEventProcessor treeEventProcessor = new TreeEventProcessor(editingContext, this.treeService, treeCreationParameters, this.treeEventHandlers,
this.subscriptionManagerFactory.create(), new SimpleMeterRegistry(), this.representationRefreshPolicyRegistry);
return Optional.of(treeEventProcessor);
}
}
return Optional.empty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.Optional;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Predicate;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
Expand All @@ -34,7 +33,6 @@
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.sirius.components.collaborative.trees.api.ITreeConfiguration;
import org.eclipse.sirius.components.collaborative.widget.reference.api.IReferenceWidgetRootCandidateSearchProvider;
import org.eclipse.sirius.components.core.CoreImageConstants;
import org.eclipse.sirius.components.core.URLParser;
Expand Down Expand Up @@ -99,34 +97,28 @@ public ModelBrowsersDescriptionProvider(IObjectService objectService, IURLParser

@Override
public List<IRepresentationDescription> getRepresentationDescriptions(IEditingContext editingContext) {
Predicate<VariableManager> containerDescriptionCanCreatePredicate = variableManager -> variableManager.get(ITreeConfiguration.TREE_ID, String.class)
.map(treeId -> treeId.startsWith(MODEL_BROWSER_CONTAINER_PREFIX))
.orElse(false);
Function<VariableManager, Boolean> containerDescriptionIsSelectableProvider = variableManager -> {
EClass referenceKind = this.resolveReferenceEClass(variableManager).orElse(null);
return this.isContainerSelectable(variableManager, referenceKind);
};
var containerDescription = this.getModelBrowserDescription(CONTAINER_DESCRIPTION_ID, containerDescriptionCanCreatePredicate, containerDescriptionIsSelectableProvider, this::getCreationScopeElements);
var containerDescription = this.getModelBrowserDescription(CONTAINER_DESCRIPTION_ID, containerDescriptionIsSelectableProvider, this::getCreationScopeElements, MODEL_BROWSER_CONTAINER_PREFIX);

Predicate<VariableManager> referenceDescriptionCanCreatePredicate = variableManager -> variableManager.get(ITreeConfiguration.TREE_ID, String.class)
.map(treeId -> treeId.startsWith(MODEL_BROWSER_REFERENCE_PREFIX))
.orElse(false);
Function<VariableManager, Boolean> referenceDescriptionIsSelectableProvider = variableManager -> {
EClass targetType = this.resolveTargetType(variableManager).orElse(null);
boolean isContainment = this.resolveIsContainment(variableManager);
return this.isTypeSelectable(variableManager, targetType, isContainment);
};
var referenceDescription = this.getModelBrowserDescription(REFERENCE_DESCRIPTION_ID, referenceDescriptionCanCreatePredicate, referenceDescriptionIsSelectableProvider, this::getSearchScopeElements);
var referenceDescription = this.getModelBrowserDescription(REFERENCE_DESCRIPTION_ID, referenceDescriptionIsSelectableProvider, this::getSearchScopeElements, MODEL_BROWSER_REFERENCE_PREFIX);

return List.of(containerDescription, referenceDescription);
}

private TreeDescription getModelBrowserDescription(String descriptionId, Predicate<VariableManager> canCreatePredicate, Function<VariableManager, Boolean> isSelectableProvider,
Function<VariableManager, List<?>> elementsProvider) {
private TreeDescription getModelBrowserDescription(String descriptionId, Function<VariableManager, Boolean> isSelectableProvider,
Function<VariableManager, List<?>> elementsProvider, String treeId) {

return TreeDescription.newTreeDescription(descriptionId)
.label(REPRESENTATION_NAME)
.idProvider(variableManager -> variableManager.get(ITreeConfiguration.TREE_ID, String.class).orElse(null))
.idProvider(variableManager -> variableManager.get(GetOrCreateRandomIdProvider.PREVIOUS_REPRESENTATION_ID, String.class).orElse(treeId))
.treeItemIdProvider(this::getTreeItemId)
.kindProvider(this::getKind)
.labelProvider(this::getLabel)
Expand All @@ -140,7 +132,7 @@ private TreeDescription getModelBrowserDescription(String descriptionId, Predica
.childrenProvider(variableManager -> this.getChildren(variableManager, isSelectableProvider))
// This predicate will NOT be used while creating the model browser, but we don't want to see the description of the
// model browser in the list of representations that can be created. Thus, we will return false all the time.
.canCreatePredicate(canCreatePredicate)
.canCreatePredicate(variableManager -> false)
.deleteHandler(this::getDeleteHandler)
.renameHandler(this::getRenameHandler)
.treeItemObjectProvider(this::getTreeItemObject)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.components.collaborative.widget.reference.configurations;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;

import org.eclipse.sirius.components.collaborative.api.IRepresentationConfiguration;
import org.eclipse.sirius.components.collaborative.widget.reference.browser.ModelBrowsersDescriptionProvider;

/**
* The configuration of the model browser event processor.
*
* @author Jerome Gout
*/
public class ModelBrowserConfiguration implements IRepresentationConfiguration {

private final String treeId;

private final List<String> expanded;

public ModelBrowserConfiguration(String editingContextId, String treeId, List<String> expanded) {
this.expanded = Objects.requireNonNull(expanded);

StringBuilder idBuilder = new StringBuilder(treeId);
if (treeId.endsWith(ModelBrowsersDescriptionProvider.MODEL_BROWSER_CONTAINER_PREFIX) || treeId.endsWith(ModelBrowsersDescriptionProvider.MODEL_BROWSER_REFERENCE_PREFIX)) {
idBuilder.append("?");
} else {
idBuilder.append("&");
}

List<String> expandedObjectIds = expanded.stream().map(id -> URLEncoder.encode(id, StandardCharsets.UTF_8)).toList();
idBuilder.append("expandedIds=[").append(String.join(",", expandedObjectIds)).append("]");

this.treeId = idBuilder.toString();
}

@Override
public String getId() {
return this.treeId;
}

public List<String> getExpanded() {
return this.expanded;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.components.collaborative.trees.api;
package org.eclipse.sirius.components.collaborative.widget.reference.dto;

import org.eclipse.sirius.components.collaborative.api.IRepresentationConfiguration;
import java.util.List;
import java.util.UUID;

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

/**
* The configuration of the tree event processor.
* The input of the model browser event subscription.
*
* @author Jerome Gout
*/
public interface ITreeConfiguration extends IRepresentationConfiguration {

String TREE_ID = "treeId";
public record ModelBrowserEventInput(UUID id, String editingContextId, String treeId, List<String> expanded) implements IInput {
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import java.util.List;

import org.eclipse.sirius.components.collaborative.trees.api.ITreeConfiguration;
import org.eclipse.sirius.components.collaborative.widget.reference.browser.ModelBrowsersDescriptionProvider;
import org.eclipse.sirius.components.core.URLParser;
import org.eclipse.sirius.components.core.api.IEditingContext;
Expand Down Expand Up @@ -55,15 +54,13 @@ public void testModelBrowserDescriptionProvider() {
variableManager.put(IEditingContext.EDITING_CONTEXT, editingContext);

var referenceTreeId = "modelBrowser://reference";
variableManager.put(ITreeConfiguration.TREE_ID, referenceTreeId);
var tree = new TreeRenderer(variableManager, referenceBrowserDescription.get()).render();
assertThat(tree).isNotNull();
assertThat(tree.getId()).isEqualTo(referenceTreeId);
assertThat(tree.getDescriptionId()).isEqualTo(ModelBrowsersDescriptionProvider.REFERENCE_DESCRIPTION_ID);
assertThat(tree.getKind()).isEqualTo(Tree.KIND);

var containerTreeId = "modelBrowser://container";
variableManager.put(ITreeConfiguration.TREE_ID, containerTreeId);
tree = new TreeRenderer(variableManager, containerBrowserDescription.get()).render();
assertThat(tree).isNotNull();
assertThat(tree.getId()).isEqualTo(containerTreeId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.components.widget.reference.graphql.datafetchers.subscription;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.eclipse.sirius.components.annotations.spring.graphql.SubscriptionDataFetcher;
import org.eclipse.sirius.components.collaborative.widget.reference.configurations.ModelBrowserConfiguration;
import org.eclipse.sirius.components.collaborative.widget.reference.dto.ModelBrowserEventInput;
import org.eclipse.sirius.components.core.api.IPayload;
import org.eclipse.sirius.components.graphql.api.IDataFetcherWithFieldCoordinates;
import org.eclipse.sirius.components.graphql.api.IEventProcessorSubscriptionProvider;
import org.eclipse.sirius.components.graphql.api.IExceptionWrapper;
import org.eclipse.sirius.components.graphql.api.LocalContextConstants;
import org.reactivestreams.Publisher;

import graphql.execution.DataFetcherResult;
import graphql.schema.DataFetchingEnvironment;

/**
* The data fetcher used to send the refreshed tree to a model browser subscription .
*
* @author Jerome Gout
*/
@SubscriptionDataFetcher(type = "Subscription", field = "modelBrowserEvent")
public class SubscriptionModelBrowserEventDataFetcher implements IDataFetcherWithFieldCoordinates<Publisher<DataFetcherResult<IPayload>>> {

private static final String INPUT_ARGUMENT = "input";

private final ObjectMapper objectMapper;

private final IExceptionWrapper exceptionWrapper;

private final IEventProcessorSubscriptionProvider eventProcessorSubscriptionProvider;

public SubscriptionModelBrowserEventDataFetcher(ObjectMapper objectMapper, IExceptionWrapper exceptionWrapper, IEventProcessorSubscriptionProvider eventProcessorSubscriptionProvider) {
this.objectMapper = Objects.requireNonNull(objectMapper);
this.exceptionWrapper = Objects.requireNonNull(exceptionWrapper);
this.eventProcessorSubscriptionProvider = Objects.requireNonNull(eventProcessorSubscriptionProvider);
}

@Override
public Publisher<DataFetcherResult<IPayload>> get(DataFetchingEnvironment environment) throws Exception {
Object argument = environment.getArgument(INPUT_ARGUMENT);
var input = this.objectMapper.convertValue(argument, ModelBrowserEventInput.class);
var modelBrowserConfiguration = new ModelBrowserConfiguration(input.editingContextId(), input.treeId(), input.expanded());

Map<String, Object> localContext = new HashMap<>();
localContext.put(LocalContextConstants.EDITING_CONTEXT_ID, input.editingContextId());
localContext.put(LocalContextConstants.REPRESENTATION_ID, modelBrowserConfiguration.getId());

return this.exceptionWrapper.wrapFlux(() -> this.eventProcessorSubscriptionProvider.getSubscription(input.editingContextId(), modelBrowserConfiguration, input), input)
.map(payload -> DataFetcherResult.<IPayload>newResult()
.data(payload)
.localContext(localContext)
.build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
extend type Subscription {
modelBrowserEvent(input: ModelBrowserEventInput!): TreeEventPayload!
}

input ModelBrowserEventInput {
id: ID!
treeId: String!
editingContextId: ID!
expanded: [String!]!
}
Loading

0 comments on commit 98578a3

Please sign in to comment.