Skip to content

Commit

Permalink
[1985] Add support for in-memory Views
Browse files Browse the repository at this point in the history
Bug: #1985
Signed-off-by: Pierre-Charles David <pierre-charles.david@obeo.fr>
  • Loading branch information
pcdavid authored and sbegaudeau committed May 25, 2023
1 parent e99f14d commit 6926198
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 16 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ The filter button inside the filter bar allows to filter (hide) all visible tree
image:doc/screenshots/filterBarFilterButton.png[Filter Bar Filter Button,30%,30%]

- https://github.com/eclipse-sirius/sirius-components/issues/1830[#1830] [layout] This feature is experimental and can be activated on a diagram by adding "__EXPERIMENTAL" to its name. The new algorithm does the minimum possible to place node without overlap.
- https://github.com/eclipse-sirius/sirius-components/issues/1985[|#1985] [sirius-web] It is now possible to use in-memory View-based representations by registering them in the new `InMemoryViewRegistry`.
These representations can be created programmatically or loaded from `.view` EMF models on startup, and do not need to be stored as documents inside a project in the database.

=== Improvements

Expand Down
5 changes: 5 additions & 0 deletions packages/sirius-web/backend/sirius-web-services-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@
<artifactId>sirius-components-representations</artifactId>
<version>2023.4.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-view</artifactId>
<version>2023.4.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-graphql-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*******************************************************************************
* 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.services.api.representations;

import java.util.Optional;

import org.eclipse.sirius.components.view.View;

/**
* Used to register views loaded in memory.
*
* @author pcdavid
*/
public interface IInMemoryViewRegistry {

void register(View view);

Optional<View> findViewById(String viewId);
}
Original file line number Diff line number Diff line change
@@ -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.web.services.representations;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import org.eclipse.sirius.components.view.View;
import org.eclipse.sirius.web.services.api.representations.IInMemoryViewRegistry;
import org.springframework.stereotype.Service;

/**
* Used to register views loaded in memory.
*
* @author pcdavid
*/
@Service
public class InMemoryViewRegistry implements IInMemoryViewRegistry {

private final Map<String, View> idToView = new HashMap<>();

@Override
public void register(View view) {
String viewId = view.eResource().getURI().toString().split("///")[1];
this.idToView.put(viewId, view);
}

@Override
public Optional<View> findViewById(String viewId) {
return Optional.ofNullable(this.idToView.get(viewId));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.eclipse.sirius.emfjson.resource.JsonResource;
import org.eclipse.sirius.web.persistence.entities.DocumentEntity;
import org.eclipse.sirius.web.persistence.repositories.IDocumentRepository;
import org.eclipse.sirius.web.services.api.representations.IInMemoryViewRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
Expand All @@ -62,6 +63,8 @@ public class ViewRepresentationDescriptionSearchService implements IViewRepresen

private final EPackage.Registry ePackageRegistry;

private final IInMemoryViewRegistry inMemoryViewRegistry;

private final IDiagramIdProvider diagramIdProvider;

private final IURLParser urlParser;
Expand All @@ -70,23 +73,23 @@ public class ViewRepresentationDescriptionSearchService implements IViewRepresen

private final IObjectService objectService;

public ViewRepresentationDescriptionSearchService(IDocumentRepository documentRepository, EPackage.Registry ePackageRegistry, IDiagramIdProvider diagramIdProvider, IURLParser urlParser, IFormIdProvider formIdProvider, IObjectService objectService) {
public ViewRepresentationDescriptionSearchService(IDocumentRepository documentRepository, EPackage.Registry ePackageRegistry, IDiagramIdProvider diagramIdProvider, IURLParser urlParser, IFormIdProvider formIdProvider, IObjectService objectService, IInMemoryViewRegistry inMemoryViewRegistry) {
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);
this.inMemoryViewRegistry = Objects.requireNonNull(inMemoryViewRegistry);
}

@Override
public Optional<RepresentationDescription> findById(String representationDescriptionId) {
Optional<String> sourceId = this.getSourceId(representationDescriptionId);
if (sourceId.isPresent()) {
Optional<DocumentEntity> documentEntity = this.documentRepository.findById(UUID.fromString(sourceId.get()));
if (documentEntity.isPresent()) {
Resource resource = this.loadDocumentAsEMF(documentEntity.get());
var searchedView = this.getViewDefinitions(resource)
List<View> views = this.getViewsFromSourceId(sourceId.get());
if (!views.isEmpty()) {
var searchedView = views.stream()
.flatMap(view -> view.getDescriptions().stream())
.filter(representationDescription -> representationDescriptionId.equals(this.getRepresentationDescriptionId(representationDescription)))
.findFirst();
Expand All @@ -101,18 +104,18 @@ public Optional<RepresentationDescription> findById(String representationDescrip
public Optional<NodeDescription> findViewNodeDescriptionById(String nodeDescriptionId) {
Optional<String> sourceId = this.getSourceId(nodeDescriptionId);
Optional<String> sourceElementId = this.getSourceElementId(nodeDescriptionId);

if (sourceId.isPresent() && sourceElementId.isPresent()) {
Optional<DocumentEntity> documentEntity = this.documentRepository.findById(UUID.fromString(sourceId.get()));
if (documentEntity.isPresent()) {
Resource resource = this.loadDocumentAsEMF(documentEntity.get());
var searchedViewNodes = this.getViewDefinitions(resource)
List<View> views = this.getViewsFromSourceId(sourceId.get());
if (!views.isEmpty()) {
// @formatter:off
var searchedViewNodes = views.stream()
.flatMap(view -> view.getDescriptions().stream())
.filter(DiagramDescription.class::isInstance)
.map(DiagramDescription.class::cast)
.map(diagramDescription -> this.findNodeDescriptionById(diagramDescription, sourceElementId.get()))
.flatMap(Optional::stream)
.findFirst();
// @formatter:on
return searchedViewNodes;
}
}
Expand All @@ -123,24 +126,37 @@ public Optional<NodeDescription> findViewNodeDescriptionById(String nodeDescript
public Optional<EdgeDescription> findViewEdgeDescriptionById(String edgeDescriptionId) {
Optional<String> sourceId = this.getSourceId(edgeDescriptionId);
Optional<String> sourceElementId = this.getSourceElementId(edgeDescriptionId);

if (sourceId.isPresent() && sourceElementId.isPresent()) {
Optional<DocumentEntity> documentEntity = this.documentRepository.findById(UUID.fromString(sourceId.get()));
if (documentEntity.isPresent()) {
Resource resource = this.loadDocumentAsEMF(documentEntity.get());
var searchedViewEdges = this.getViewDefinitions(resource)
List<View> views = this.getViewsFromSourceId(sourceId.get());
if (!views.isEmpty()) {
// @formatter:off
var searchedViewNodes = views.stream()
.flatMap(view -> view.getDescriptions().stream())
.filter(DiagramDescription.class::isInstance)
.map(DiagramDescription.class::cast)
.map(diagramDescription -> this.findEdgeDescriptionById(diagramDescription, sourceElementId.get()))
.flatMap(Optional::stream)
.findFirst();
return searchedViewEdges;
// @formatter:on
return searchedViewNodes;
}
}
return Optional.empty();
}

private List<View> getViewsFromSourceId(String sourceId) {
List<View> views = this.inMemoryViewRegistry.findViewById(sourceId).stream().toList();
if (views.isEmpty()) {
Optional<DocumentEntity> documentEntity = this.documentRepository.findById(UUID.fromString(sourceId));
if (documentEntity.isPresent()) {
Resource resource = this.loadDocumentAsEMF(documentEntity.get());
views = this.getViewDefinitions(resource).toList();
}
}

return views;
}

private Resource loadDocumentAsEMF(DocumentEntity documentEntity) {
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.setPackageRegistry(this.ePackageRegistry);
Expand Down

0 comments on commit 6926198

Please sign in to comment.