Skip to content

Commit

Permalink
[3961] Extend the explorer to support multiple presentations
Browse files Browse the repository at this point in the history
default explorer + one custom explorer for Domain

Bug: eclipse-sirius#3961
Signed-off-by: Jerome Gout <[email protected]>
  • Loading branch information
jerome-obeo committed Sep 13, 2024
1 parent 94e74b7 commit c12e21e
Show file tree
Hide file tree
Showing 35 changed files with 916 additions and 31 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
- https://github.com/eclipse-sirius/sirius-web/issues/3987[#3987] [sirius-web] Transform `widgetFields` fragment to retrieve custom widget fields
- https://github.com/eclipse-sirius/sirius-web/issues/3875[#3875] [sirius-web] Move explorer related code from `sirius-components-trees` to `sirius-web-application`
- https://github.com/eclipse-sirius/sirius-web/issues/3882[#3882] [sirius-web] Add a new tree event to handle tree description which are not explorer-related
- https://github.com/eclipse-sirius/sirius-web/issues/3961[#3961] [sirius-web] Extend the explorer to support multiple presentations

== v2024.9.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.eclipse.sirius.components.collaborative.api.IRepresentationConfiguration;
import org.eclipse.sirius.components.core.URLParser;
import org.eclipse.sirius.web.application.views.explorer.services.ExplorerDescriptionProvider;

/**
* The configuration of the explorer event processor.
Expand Down Expand Up @@ -57,6 +60,15 @@ public String getId() {
return this.treeId;
}

public String getTreeDescriptionId() {
Map<String, List<String>> parameters = new URLParser().getParameterValues(this.treeId);
List<String> treeDescriptionId = parameters.get("treeDescriptionId");
if (treeDescriptionId == null) {
return ExplorerDescriptionProvider.DESCRIPTION_ID;
}
return treeDescriptionId.get(0);
}

public List<String> getActiveFilterIds() {
return this.activeFilterIds;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
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.eclipse.sirius.web.application.views.explorer.services.ExplorerDescriptionProvider;
import org.springframework.stereotype.Service;

import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
Expand Down Expand Up @@ -73,7 +72,7 @@ public Optional<IRepresentationEventProcessor> createRepresentationEventProcesso
if (configuration instanceof ExplorerConfiguration treeConfiguration) {

Optional<TreeDescription> optionalTreeDescription = this.representationDescriptionSearchService
.findById(editingContext, ExplorerDescriptionProvider.DESCRIPTION_ID)
.findById(editingContext, treeConfiguration.getTreeDescriptionId())
.filter(TreeDescription.class::isInstance)
.map(TreeDescription.class::cast);
if (optionalTreeDescription.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.web.application.views.explorer.controllers;

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

import org.eclipse.sirius.components.annotations.spring.graphql.QueryDataFetcher;
import org.eclipse.sirius.components.graphql.api.IDataFetcherWithFieldCoordinates;
import org.eclipse.sirius.components.graphql.api.IEditingContextDispatcher;
import org.eclipse.sirius.web.application.views.explorer.dto.EditingContextExplorerDescriptionsInput;
import org.eclipse.sirius.web.application.views.explorer.dto.EditingContextExplorerDescriptionsPayload;
import org.eclipse.sirius.web.application.views.explorer.dto.ExplorerDescriptionMetadata;

import graphql.schema.DataFetchingEnvironment;

/**
* Data fetcher for the EditingContext#explorerDescriptions.
*
* @author Jerome Gout
*/
@QueryDataFetcher(type = "EditingContext", field = "explorerDescriptions")
public class EditingContextExplorerDescriptionsDataFetcher implements IDataFetcherWithFieldCoordinates<CompletableFuture<List<ExplorerDescriptionMetadata>>> {

private final IEditingContextDispatcher editingContextDispatcher;

public EditingContextExplorerDescriptionsDataFetcher(IEditingContextDispatcher editingContextDispatcher) {
this.editingContextDispatcher = Objects.requireNonNull(editingContextDispatcher);
}

@Override
public CompletableFuture<List<ExplorerDescriptionMetadata>> get(DataFetchingEnvironment environment) throws Exception {
String editingContextId = environment.getSource();
var input = new EditingContextExplorerDescriptionsInput(UUID.randomUUID(), editingContextId);
return this.editingContextDispatcher.dispatchQuery(input.editingContextId(), input)
.filter(EditingContextExplorerDescriptionsPayload.class::isInstance)
.map(EditingContextExplorerDescriptionsPayload.class::cast)
.map(EditingContextExplorerDescriptionsPayload::explorerDescriptionMetadata)
.toFuture();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.web.application.views.explorer.dto;

import java.util.UUID;

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

import jakarta.validation.constraints.NotNull;

/**
* The input object for the query field explorerDescriptions.
*
* @author Jerome Gout
*/
public record EditingContextExplorerDescriptionsInput(@NotNull UUID id, @NotNull String editingContextId) implements IInput { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.web.application.views.explorer.dto;

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

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

import jakarta.validation.constraints.NotNull;

/**
* The payload object for the query field explorerDescriptions.
*
* @author Jerome Gout
*/
public record EditingContextExplorerDescriptionsPayload(@NotNull UUID id, @NotNull List<ExplorerDescriptionMetadata> explorerDescriptionMetadata) implements IPayload { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.web.application.views.explorer.dto;

import jakarta.validation.constraints.NotNull;

/**
* The metadata of an explorer description.
*
* @author Jerome Gout
*/
public record ExplorerDescriptionMetadata(@NotNull String id, @NotNull String label) { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.web.application.views.explorer.handlers;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.eclipse.sirius.components.collaborative.api.ChangeDescription;
import org.eclipse.sirius.components.collaborative.api.IEditingContextEventHandler;
import org.eclipse.sirius.components.core.api.IEditingContext;
import org.eclipse.sirius.components.core.api.IInput;
import org.eclipse.sirius.components.core.api.IPayload;
import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService;
import org.eclipse.sirius.components.trees.description.TreeDescription;
import org.eclipse.sirius.web.application.views.explorer.dto.EditingContextExplorerDescriptionsInput;
import org.eclipse.sirius.web.application.views.explorer.dto.EditingContextExplorerDescriptionsPayload;
import org.eclipse.sirius.web.application.views.explorer.dto.ExplorerDescriptionMetadata;
import org.eclipse.sirius.web.application.views.explorer.services.ExplorerDescriptionProvider;
import org.eclipse.sirius.web.application.views.explorer.services.api.IExplorerDescriptionMapper;
import org.eclipse.sirius.web.application.views.explorer.services.api.IExplorerTreeDescriptionProvider;
import org.springframework.stereotype.Service;

import reactor.core.publisher.Sinks;

/**
* Event handler to find all the explorer descriptions accessible from a given editing context.
*
* @author Jerome Gout
*/
@Service
public class EditingContextExplorerDescriptionEventHandler implements IEditingContextEventHandler {


private final IExplorerDescriptionMapper explorerDescriptionMapper;

private final IRepresentationDescriptionSearchService representationDescriptionSearchService;

private final List<IExplorerTreeDescriptionProvider> explorerTreeDescriptionProviders;

public EditingContextExplorerDescriptionEventHandler(IExplorerDescriptionMapper explorerDescriptionMapper, IRepresentationDescriptionSearchService representationDescriptionSearchService, List<IExplorerTreeDescriptionProvider> explorerTreeDescriptionProviders) {
this.explorerDescriptionMapper = Objects.requireNonNull(explorerDescriptionMapper);
this.representationDescriptionSearchService = representationDescriptionSearchService;
this.explorerTreeDescriptionProviders = explorerTreeDescriptionProviders;
}

@Override
public boolean canHandle(IEditingContext editingContext, IInput input) {
return input instanceof EditingContextExplorerDescriptionsInput;
}

@Override
public void handle(Sinks.One<IPayload> payloadSink, Sinks.Many<ChangeDescription> changeDescriptionSink, IEditingContext editingContext, IInput input) {
List<ExplorerDescriptionMetadata> explorerDescriptions = List.of();
if (input instanceof EditingContextExplorerDescriptionsInput) {
explorerDescriptions = this.findAllExplorerTreeDescriptions(editingContext);
}
payloadSink.tryEmitValue(new EditingContextExplorerDescriptionsPayload(input.id(), explorerDescriptions));
}

List<ExplorerDescriptionMetadata> findAllExplorerTreeDescriptions(IEditingContext editingContext) {
var optionalDefaultExplorerDescription = this.representationDescriptionSearchService.findById(editingContext, ExplorerDescriptionProvider.DESCRIPTION_ID)
.filter(TreeDescription.class::isInstance)
.map(TreeDescription.class::cast);

var explorers = this.explorerTreeDescriptionProviders.stream()
.flatMap(provider -> provider.getDescriptions(editingContext).stream())
.map(this.explorerDescriptionMapper::toDTO)
.sorted(Comparator.comparing(ExplorerDescriptionMetadata::label))
.collect(Collectors.toList());

optionalDefaultExplorerDescription.ifPresent(treeDescription -> explorers.add(this.explorerDescriptionMapper.toDTO(treeDescription)));
return explorers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.web.application.views.explorer.services;

import org.eclipse.sirius.components.trees.description.TreeDescription;
import org.eclipse.sirius.web.application.views.explorer.dto.ExplorerDescriptionMetadata;
import org.eclipse.sirius.web.application.views.explorer.services.api.IExplorerDescriptionMapper;
import org.springframework.stereotype.Service;

/**
* Used to convert an explorer candidate to a DTO.
*
* @author Jerome Gout
*/
@Service
public class ExplorerDescriptionMapper implements IExplorerDescriptionMapper {

@Override
public ExplorerDescriptionMetadata toDTO(TreeDescription treeDescription) {
return new ExplorerDescriptionMetadata(treeDescription.getId(), treeDescription.getLabel());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private String getExplorerTreeId(List<?> expandedObjects, List<?> activatedFilte
.map(id -> URLEncoder.encode(id, StandardCharsets.UTF_8))
.toList();

return "explorer://?expandedIds=[" + String.join(",", expandedObjectIds) + "]&activeFilterIds=[" + String.join(",", activatedFilterIds) + "]";
return "explorer://?treeDescriptionId=" + DESCRIPTION_ID + "&expandedIds=[" + String.join(",", expandedObjectIds) + "]&activeFilterIds=[" + String.join(",", activatedFilterIds) + "]";
}

private String getTreeItemId(VariableManager variableManager) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.web.application.views.explorer.services.api;

import org.eclipse.sirius.components.trees.description.TreeDescription;
import org.eclipse.sirius.web.application.views.explorer.dto.ExplorerDescriptionMetadata;

/**
* Used to convert an explorer candidate to a DTO.
*
* @author Jerome Gout
*/
public interface IExplorerDescriptionMapper {
ExplorerDescriptionMetadata toDTO(TreeDescription treeDescription);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.web.application.views.explorer.services.api;

import java.util.List;

import org.eclipse.sirius.components.core.api.IEditingContext;
import org.eclipse.sirius.components.trees.description.TreeDescription;

/**
* Interface to provide tree descriptions that could be used inside the explorer of Sirius web.
*
* @author Jerome Gout
*/
public interface IExplorerTreeDescriptionProvider {

List<TreeDescription> getDescriptions(IEditingContext editinContext);
}
Loading

0 comments on commit c12e21e

Please sign in to comment.