Skip to content

Commit

Permalink
[2926] Introduce IEditingContextProcessor
Browse files Browse the repository at this point in the history
Bug: #2926
Signed-off-by: Axel RICHARD <axel.richard@obeo.fr>
  • Loading branch information
AxelRICHARD committed Jan 15, 2024
1 parent 241377b commit 410af2f
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 34 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Expand Up @@ -124,6 +124,7 @@ Now, for a multi-valued feature, the values are properly displayed and the delet
+
The size of nodes that do not have been resized manually tries to fit the node default size.
- https://github.com/eclipse-sirius/sirius-web/issues/2792[#2792] [diagram] Add a first version for arrange all support.
- https://github.com/eclipse-sirius/sirius-web/issues/2926[#2926] [sirius-web] Add a first version of the support fro libraries.

=== Improvements

Expand Down
@@ -0,0 +1,40 @@
/*******************************************************************************
* 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.core.api;

/**
* Processor for {@link IEditingContext}.
*
* @author arichard
*/
public interface IEditingContextProcessor {

void preProcess(IEditingContext editingContext);
void postProcess(IEditingContext editingContext);

/**
* Implementation which does nothing, used for mocks in unit tests.
*
* @author arichard
*/
class NoOp implements IEditingContextProcessor {

@Override
public void preProcess(IEditingContext editingContext) {
}

@Override
public void postProcess(IEditingContext editingContext) {
}
}
}
Expand Up @@ -14,36 +14,34 @@

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.sirius.components.core.api.IEditingContext;
import org.eclipse.sirius.components.core.api.IEditingContextProcessor;
import org.eclipse.sirius.components.core.api.IEditingContextSearchService;
import org.eclipse.sirius.components.core.configuration.IRepresentationDescriptionRegistryConfigurer;
import org.eclipse.sirius.components.emf.ResourceMetadataAdapter;
import org.eclipse.sirius.components.emf.services.EditingContextCrossReferenceAdapter;
import org.eclipse.sirius.components.emf.services.JSONResourceFactory;
import org.eclipse.sirius.components.representations.IRepresentationDescription;
import org.eclipse.sirius.components.view.View;
import org.eclipse.sirius.components.view.emf.IViewConverter;
import org.eclipse.sirius.components.view.util.services.ColorPaletteService;
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.persistence.repositories.IProjectRepository;
import org.eclipse.sirius.web.services.api.id.IDParser;
import org.eclipse.sirius.web.services.editingcontext.api.IEditingDomainFactoryService;
import org.eclipse.sirius.web.services.editingcontext.api.IViewLoader;
import org.eclipse.sirius.web.services.representations.RepresentationDescriptionRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -72,21 +70,17 @@ public class EditingContextSearchService implements IEditingContextSearchService

private final List<IRepresentationDescriptionRegistryConfigurer> configurers;

private final IViewLoader viewLoader;

private final IViewConverter viewConverter;
private final List<IEditingContextProcessor> editingContextProcessors;

private final Timer timer;

public EditingContextSearchService(IProjectRepository projectRepository, IDocumentRepository documentRepository, IEditingDomainFactoryService editingDomainFactoryService,
List<IRepresentationDescriptionRegistryConfigurer> configurers, IViewLoader viewLoader, IViewConverter viewConverter, MeterRegistry meterRegistry) {
List<IRepresentationDescriptionRegistryConfigurer> configurers, List<IEditingContextProcessor> editingContextProcessors, MeterRegistry meterRegistry) {
this.projectRepository = Objects.requireNonNull(projectRepository);
this.documentRepository = Objects.requireNonNull(documentRepository);
this.editingDomainFactoryService = Objects.requireNonNull(editingDomainFactoryService);
this.configurers = Objects.requireNonNull(configurers);
this.viewLoader = Objects.requireNonNull(viewLoader);
this.viewConverter = Objects.requireNonNull(viewConverter);

this.editingContextProcessors = Objects.requireNonNull(editingContextProcessors);
this.timer = Timer.builder(TIMER_NAME).register(meterRegistry);
}

Expand All @@ -106,6 +100,12 @@ public Optional<IEditingContext> findById(String editingContextId) {
resourceSet.getLoadOptions().put(JsonResource.OPTION_EXTENDED_META_DATA, new BasicExtendedMetaData(resourceSet.getPackageRegistry()));
resourceSet.getLoadOptions().put(JsonResource.OPTION_SCHEMA_LOCATION, true);

Map<String, IRepresentationDescription> representationDescriptions = new HashMap<>();

EditingContext editingContext = new EditingContext(editingContextId, editingDomain, representationDescriptions, new ArrayList<>());
this.editingContextProcessors.forEach(processor -> processor.preProcess(editingContext));


List<DocumentEntity> documentEntities = new IDParser().parse(editingContextId)
.map(this.documentRepository::findAllByProjectId)
.orElseGet(List::of)
Expand All @@ -132,36 +132,23 @@ public Optional<IEditingContext> findById(String editingContextId) {

this.logger.debug("{} documents loaded for the editing context {}", resourceSet.getResources().size(), editingContextId);

var views = this.viewLoader.load();
Map<String, IRepresentationDescription> representationDescriptions = this.getRepresentationDescriptions(editingDomain, views);
representationDescriptions = this.getRepresentationDescriptions();

this.editingContextProcessors.forEach(processor -> processor.postProcess(editingContext));

long end = System.currentTimeMillis();
this.timer.record(end - start, TimeUnit.MILLISECONDS);

return Optional.of(new EditingContext(editingContextId, editingDomain, representationDescriptions, views));
return Optional.of(editingContext);
}

private Map<String, IRepresentationDescription> getRepresentationDescriptions(EditingDomain editingDomain, List<View> views) {
private Map<String, IRepresentationDescription> getRepresentationDescriptions() {
Map<String, IRepresentationDescription> representationDescriptions = new LinkedHashMap<>();
var registry = new RepresentationDescriptionRegistry();
this.configurers.forEach(configurer -> configurer.addRepresentationDescriptions(registry));
registry.getRepresentationDescriptions().forEach(representationDescription -> representationDescriptions.put(representationDescription.getId(), representationDescription));

List<EPackage> accessibleEPackages = this.getAccessibleEPackages(editingDomain);
this.viewConverter.convert(views, accessibleEPackages).stream()
.filter(Objects::nonNull)
.forEach(representationDescription -> representationDescriptions.put(representationDescription.getId(), representationDescription));

return representationDescriptions;
}

private List<EPackage> getAccessibleEPackages(EditingDomain editingDomain) {
var packageRegistry = editingDomain.getResourceSet().getPackageRegistry();

return packageRegistry.values().stream()
.filter(EPackage.class::isInstance)
.map(EPackage.class::cast)
.toList();
}

}
@@ -0,0 +1,69 @@
/*******************************************************************************
* 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.services.editingcontext;

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

import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.sirius.components.core.api.IEditingContext;
import org.eclipse.sirius.components.core.api.IEditingContextProcessor;
import org.eclipse.sirius.components.view.emf.IViewConverter;
import org.eclipse.sirius.web.services.editingcontext.api.IViewLoader;
import org.springframework.stereotype.Service;

/**
* Editing context processor allowing to convert all views.
*
* @author arichard
*/
@Service
public class ViewEditingContextProcessor implements IEditingContextProcessor {

private final IViewLoader viewLoader;

private final IViewConverter viewConverter;

public ViewEditingContextProcessor(IViewLoader viewLoader, IViewConverter viewConverter) {
this.viewLoader = viewLoader;
this.viewConverter = viewConverter;

}
@Override
public void preProcess(IEditingContext editingContext) {
if (editingContext instanceof EditingContext siriusWebEditingContext) {
siriusWebEditingContext.getViews().addAll(this.viewLoader.load());
}

}

@Override
public void postProcess(IEditingContext editingContext) {
if (editingContext instanceof EditingContext siriusWebEditingContext) {
List<EPackage> accessibleEPackages = this.getAccessibleEPackages(siriusWebEditingContext.getDomain());
this.viewConverter.convert(siriusWebEditingContext.getViews(), accessibleEPackages).stream()
.filter(Objects::nonNull)
.forEach(representationDescription -> siriusWebEditingContext.getRepresentationDescriptions().put(representationDescription.getId(), representationDescription));
}
}

private List<EPackage> getAccessibleEPackages(EditingDomain editingDomain) {
var packageRegistry = editingDomain.getResourceSet().getPackageRegistry();

return packageRegistry.values().stream()
.filter(EPackage.class::isInstance)
.map(EPackage.class::cast)
.toList();
}
}
Expand Up @@ -18,25 +18,26 @@
import java.util.Optional;
import java.util.UUID;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.sirius.components.core.api.IEditingContext;
import org.eclipse.sirius.components.core.api.IEditingContextProcessor;
import org.eclipse.sirius.components.core.api.IEditingContextSearchService;
import org.eclipse.sirius.components.emf.ResourceMetadataAdapter;
import org.eclipse.sirius.components.emf.services.IEditingContextEPackageService;
import org.eclipse.sirius.components.emf.services.JSONResourceFactory;
import org.eclipse.sirius.components.view.emf.IViewConverter;
import org.eclipse.sirius.web.persistence.entities.DocumentEntity;
import org.eclipse.sirius.web.persistence.entities.ProjectEntity;
import org.eclipse.sirius.web.persistence.repositories.IDocumentRepository;
import org.eclipse.sirius.web.persistence.repositories.IProjectRepository;
import org.eclipse.sirius.web.services.editingcontext.api.IEditingDomainFactoryService;
import org.eclipse.sirius.web.services.editingcontext.api.IViewLoader;
import org.eclipse.sirius.web.services.projects.api.EditingContextMetadata;
import org.eclipse.sirius.web.services.projects.api.IEditingContextMetadataProvider;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -100,7 +101,7 @@ public void testEditingContextWithNoDocuments() {
IEditingDomainFactoryService editingDomainFactoryService = new EditingDomainFactoryService(editingContextEPackageService, editingContextMetadataProvider,
composedAdapterFactory, ePackageRegistry, Optional.empty());
IEditingContextSearchService editingContextSearchService = new EditingContextSearchService(projectRepository, documentRepository, editingDomainFactoryService, List.of(),
new IViewLoader.NoOp(), new IViewConverter.NoOp(), new SimpleMeterRegistry());
List.of(new IEditingContextProcessor.NoOp()), new SimpleMeterRegistry());
IEditingContext editingContext = editingContextSearchService.findById(projectId).get();

assertThat(editingContext).isInstanceOf(EditingContext.class);
Expand Down Expand Up @@ -148,7 +149,7 @@ public List<DocumentEntity> findAllByProjectId(UUID projectId) {
IEditingDomainFactoryService editingDomainFactoryService = new EditingDomainFactoryService(editingContextEPackageService, editingContextMetadataProvider,
composedAdapterFactory, ePackageRegistry, Optional.empty());
IEditingContextSearchService editingContextSearchService = new EditingContextSearchService(projectRepository, documentRepository, editingDomainFactoryService, List.of(),
new IViewLoader.NoOp(), new IViewConverter.NoOp(), new SimpleMeterRegistry());
List.of(new IEditingContextProcessor.NoOp()), new SimpleMeterRegistry());
IEditingContext editingContext = editingContextSearchService.findById(projectId.toString()).get();

assertThat(editingContext).isInstanceOf(EditingContext.class);
Expand All @@ -162,6 +163,75 @@ public List<DocumentEntity> findAllByProjectId(UUID projectId) {
this.assertProperResourceLoading(secondResource, secondDocumentEntity);
}

@Test
public void testEditingContextWithLibraries() {
UUID projectId = UUID.randomUUID();

ProjectEntity projectEntity = new ProjectEntity();
projectEntity.setId(projectId);
projectEntity.setName("");

DocumentEntity firstDocumentEntity = new DocumentEntity();
firstDocumentEntity.setId(UUID.randomUUID());
firstDocumentEntity.setName("First Document");
firstDocumentEntity.setProject(projectEntity);
firstDocumentEntity.setContent(CONTENT);

DocumentEntity secondDocumentEntity = new DocumentEntity();
secondDocumentEntity.setId(UUID.randomUUID());
secondDocumentEntity.setName("Second Document");
secondDocumentEntity.setProject(projectEntity);
secondDocumentEntity.setContent(CONTENT);

IProjectRepository projectRepository = new NoOpProjectRepository();
IDocumentRepository documentRepository = new NoOpDocumentRepository() {
@Override
public List<DocumentEntity> findAllByProjectId(UUID projectId) {
return List.of(firstDocumentEntity, secondDocumentEntity);
}
};

ComposedAdapterFactory composedAdapterFactory = new ComposedAdapterFactory();
EPackage.Registry ePackageRegistry = new EPackageRegistryImpl();
ePackageRegistry.put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);

IEditingContextEPackageService editingContextEPackageService = editingContextId -> List.of();

var editingContextMetadata = new EditingContextMetadata(List.of());
IEditingContextMetadataProvider editingContextMetadataProvider = editingContextId -> editingContextMetadata;

IEditingDomainFactoryService editingDomainFactoryService = new EditingDomainFactoryService(editingContextEPackageService, editingContextMetadataProvider,
composedAdapterFactory, ePackageRegistry, Optional.empty());

IEditingContextProcessor editingContextProcessor = new IEditingContextProcessor() {

@Override
public void preProcess(IEditingContext editingContext) {
if (editingContext instanceof EditingContext siriusWebEditingContext) {
Resource resource = new XMIResourceImpl(URI.createURI("libraryPre.json"));
siriusWebEditingContext.getDomain().getResourceSet().getResources().add(resource);
}
}

@Override
public void postProcess(IEditingContext editingContext) {
if (editingContext instanceof EditingContext siriusWebEditingContext) {
Resource resource = new XMIResourceImpl(URI.createURI("libraryPost.json"));
siriusWebEditingContext.getDomain().getResourceSet().getResources().add(resource);
}
}
};

IEditingContextSearchService editingContextSearchService = new EditingContextSearchService(projectRepository, documentRepository, editingDomainFactoryService, List.of(),
List.of(editingContextProcessor), new SimpleMeterRegistry());
IEditingContext editingContext = editingContextSearchService.findById(projectId.toString()).get();

assertThat(editingContext).isInstanceOf(EditingContext.class);
EditingDomain editingDomain = ((EditingContext) editingContext).getDomain();

assertThat(editingDomain.getResourceSet().getResources()).hasSize(4);
}

private void assertProperResourceLoading(Resource resource, DocumentEntity documentEntity) {
assertThat(resource).isNotNull();
assertThat(resource.eAdapters()).hasSize(2);
Expand Down

0 comments on commit 410af2f

Please sign in to comment.