diff --git a/packages/sirius-web/backend/sirius-web-graphql/src/main/java/org/eclipse/sirius/web/graphql/datafetchers/mutation/MutationUploadDocumentDataFetcher.java b/packages/sirius-web/backend/sirius-web-graphql/src/main/java/org/eclipse/sirius/web/graphql/datafetchers/mutation/MutationUploadDocumentDataFetcher.java index c6ea5f62ba..a4cb3de88b 100644 --- a/packages/sirius-web/backend/sirius-web-graphql/src/main/java/org/eclipse/sirius/web/graphql/datafetchers/mutation/MutationUploadDocumentDataFetcher.java +++ b/packages/sirius-web/backend/sirius-web-graphql/src/main/java/org/eclipse/sirius/web/graphql/datafetchers/mutation/MutationUploadDocumentDataFetcher.java @@ -89,7 +89,7 @@ public CompletableFuture get(DataFetchingEnvironment environment) thro .orElse(null); // @formatter:on - UploadDocumentInput input = new UploadDocumentInput(id, editingContextId, file); + UploadDocumentInput input = new UploadDocumentInput(id, editingContextId, file, true); // @formatter:off return this.editingContextEventProcessorRegistry.dispatchEvent(input.getEditingContextId(), input) diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/StereotypeBuilder.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/StereotypeBuilder.java index 94c324d997..083742ead4 100644 --- a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/StereotypeBuilder.java +++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/StereotypeBuilder.java @@ -26,7 +26,7 @@ import org.eclipse.emf.ecore.xmi.XMLParserPool; import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; import org.eclipse.emf.ecore.xmi.impl.XMLParserPoolImpl; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.components.emf.utils.EMFResourceUtils; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.slf4j.Logger; @@ -53,7 +53,7 @@ public StereotypeBuilder(String timerName, MeterRegistry meterRegistry) { } public String getStereotypeBody(EObject rootEObject) { - JsonResource resource = new SiriusWebJSONResourceFactoryImpl().createResource(URI.createURI("inmemory")); //$NON-NLS-1$ + JsonResource resource = new JSONResourceFactory().createResourceFromPath("inmemory"); //$NON-NLS-1$ if (rootEObject != null) { resource.getContents().add(rootEObject); } @@ -78,7 +78,7 @@ public String getStereotypeBody(ClassPathResource classPathResource) { String content = ""; //$NON-NLS-1$ try (var inputStream = classPathResource.getInputStream()) { - URI uri = URI.createURI(classPathResource.getFilename()); + URI uri = new JSONResourceFactory().createResourceURI(classPathResource.getFilename()); Resource inputResource = this.loadFromXMI(uri, inputStream); content = this.saveAsJSON(uri, inputResource); } catch (IOException exception) { @@ -100,7 +100,7 @@ private Resource loadFromXMI(URI uri, InputStream inputStream) throws IOExceptio private String saveAsJSON(URI uri, Resource inputResource) throws IOException { String content; - JsonResource ouputResource = new SiriusWebJSONResourceFactoryImpl().createResource(uri); + JsonResource ouputResource = new JSONResourceFactory().createResource(uri); ouputResource.getContents().addAll(inputResource.getContents()); try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { Map jsonSaveOptions = new EMFResourceUtils().getFastJSONSaveOptions(); diff --git a/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/RewriteProxiesInput.java b/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/RewriteProxiesInput.java new file mode 100644 index 0000000000..aefa3ddc09 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/RewriteProxiesInput.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2022 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.document; + +import java.text.MessageFormat; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IInput; + +/** + * The input object for the operation to rewrite broken proxy URIs in documents. + * + * @author pcdavid + */ +public final class RewriteProxiesInput implements IInput { + private final UUID id; + + private final String editingContextId; + + private final Map oldDocumentIdToNewDocumentId; + + public RewriteProxiesInput(UUID id, String editingContextId, Map oldDocumentIdToNewDocumentId) { + this.id = Objects.requireNonNull(id); + this.editingContextId = Objects.requireNonNull(editingContextId); + this.oldDocumentIdToNewDocumentId = Objects.requireNonNull(oldDocumentIdToNewDocumentId); + } + + @Override + public UUID getId() { + return this.id; + } + + public String getEditingContextId() { + return this.editingContextId; + } + + public Map getOldDocumentIdToNewDocumentId() { + return this.oldDocumentIdToNewDocumentId; + } + + @Override + public String toString() { + String pattern = "{0} '{'id: {1}, editingContextId: {2}, oldDocumentIdToNewDocumentId: {3}'}'"; //$NON-NLS-1$ + return MessageFormat.format(pattern, this.getClass().getSimpleName(), this.id, this.editingContextId, this.oldDocumentIdToNewDocumentId); + } +} diff --git a/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/RewriteProxiesSuccessPayload.java b/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/RewriteProxiesSuccessPayload.java new file mode 100644 index 0000000000..7a112fb0e2 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/RewriteProxiesSuccessPayload.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2022 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.document; + +import java.text.MessageFormat; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.core.api.IPayload; + +/** + * The payload of the rewrite proxies operation. + * + * @author pcdavid + */ +public final class RewriteProxiesSuccessPayload implements IPayload { + + private final UUID id; + + public RewriteProxiesSuccessPayload(UUID id) { + this.id = Objects.requireNonNull(id); + } + + @Override + public UUID getId() { + return this.id; + } + + @Override + public String toString() { + String pattern = "{0} '{'id: {1}'}'"; //$NON-NLS-1$ + return MessageFormat.format(pattern, this.getClass().getSimpleName(), this.id); + } +} diff --git a/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/UploadDocumentInput.java b/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/UploadDocumentInput.java index f9df1c2d6b..3dbcc60f90 100644 --- a/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/UploadDocumentInput.java +++ b/packages/sirius-web/backend/sirius-web-services-api/src/main/java/org/eclipse/sirius/web/services/api/document/UploadDocumentInput.java @@ -32,10 +32,13 @@ public final class UploadDocumentInput implements IInput { private final UploadFile file; - public UploadDocumentInput(UUID id, String editingContextId, UploadFile file) { + private final boolean checkProxies; + + public UploadDocumentInput(UUID id, String editingContextId, UploadFile file, boolean checkProxies) { this.id = Objects.requireNonNull(id); this.editingContextId = Objects.requireNonNull(editingContextId); this.file = Objects.requireNonNull(file); + this.checkProxies = checkProxies; } @Override @@ -43,6 +46,10 @@ public UUID getId() { return this.id; } + public boolean isCheckProxies() { + return this.checkProxies; + } + public String getEditingContextId() { return this.editingContextId; } diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/CreateDocumentEventHandler.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/CreateDocumentEventHandler.java index 7dfdfb5995..157950a365 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/CreateDocumentEventHandler.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/CreateDocumentEventHandler.java @@ -18,7 +18,6 @@ import java.util.Optional; import java.util.UUID; -import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.sirius.components.collaborative.api.ChangeDescription; @@ -33,7 +32,7 @@ import org.eclipse.sirius.components.core.api.IPayload; import org.eclipse.sirius.components.core.configuration.StereotypeDescription; import org.eclipse.sirius.components.emf.services.EditingContext; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.eclipse.sirius.web.services.api.document.Document; import org.eclipse.sirius.web.services.api.document.IDocumentService; @@ -136,9 +135,8 @@ private void createDocument(One payloadSink, Many c var optionalDocument = this.documentService.createDocument(editingContextId, name, stereotypeDescription.getContent()); if (optionalDocument.isPresent()) { Document document = optionalDocument.get(); - URI uri = URI.createURI(document.getId().toString()); - JsonResource resource = new SiriusWebJSONResourceFactoryImpl().createResource(uri); + JsonResource resource = new JSONResourceFactory().createResourceFromPath(document.getId().toString()); try (var inputStream = new ByteArrayInputStream(document.getContent().getBytes())) { resource.load(inputStream, null); } catch (IOException exception) { diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/DeleteDocumentEventHandler.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/DeleteDocumentEventHandler.java index f47d467fe4..bd4a8054fc 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/DeleteDocumentEventHandler.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/DeleteDocumentEventHandler.java @@ -32,6 +32,7 @@ import org.eclipse.sirius.components.core.api.IInput; import org.eclipse.sirius.components.core.api.IPayload; import org.eclipse.sirius.components.emf.services.EditingContext; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.web.services.api.document.Document; import org.eclipse.sirius.web.services.api.document.IDocumentService; import org.eclipse.sirius.web.services.messages.IServicesMessageService; @@ -96,7 +97,7 @@ public void handle(One payloadSink, Many changeDesc Document document = optionalDocument.get(); ResourceSet resourceSet = editingDomain.getResourceSet(); - URI uri = URI.createURI(document.getId().toString()); + URI uri = new JSONResourceFactory().createResourceURI(document.getId().toString()); // @formatter:off List resourcesToDelete = resourceSet.getResources().stream() diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/DocumentService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/DocumentService.java index d9a0acb977..be51712484 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/DocumentService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/DocumentService.java @@ -32,7 +32,7 @@ import org.eclipse.emf.ecore.xmi.XMIResource; import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; import org.eclipse.sirius.components.emf.services.IEditingContextEPackageService; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.eclipse.sirius.web.persistence.entities.DocumentEntity; import org.eclipse.sirius.web.persistence.repositories.IDocumentRepository; @@ -152,8 +152,7 @@ public Optional getBytes(Document document, String resourceKind) { ResourceSet resourceSet = new ResourceSetImpl(); resourceSet.setPackageRegistry(ePackageRegistryImpl); - URI uri = URI.createURI(document.getName()); - JsonResource resource = new SiriusWebJSONResourceFactoryImpl().createResource(uri); + JsonResource resource = new JSONResourceFactory().createResourceFromPath(document.getName()); resourceSet.getResources().add(resource); resourceSet.getResources().add(outputResource); diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/RenameDocumentEventHandler.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/RenameDocumentEventHandler.java index 9f080c9e94..5f57d8f8ff 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/RenameDocumentEventHandler.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/RenameDocumentEventHandler.java @@ -97,7 +97,7 @@ public void handle(One payloadSink, Many changeDesc // @formatter:off resourceSet.getResources().stream() - .filter(resource -> document.getId().toString().equals(resource.getURI().toString())) + .filter(resource -> document.getId().toString().equals(resource.getURI().path().substring(1))) .findFirst() .ifPresent(resource -> { resource.eAdapters().stream() diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/RewriteProxiesEventHandler.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/RewriteProxiesEventHandler.java new file mode 100644 index 0000000000..5b78c414c8 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/RewriteProxiesEventHandler.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2022 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.documents; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.sirius.components.collaborative.api.ChangeDescription; +import org.eclipse.sirius.components.collaborative.api.ChangeKind; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventHandler; +import org.eclipse.sirius.components.core.api.ErrorPayload; +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.emf.services.EditingContext; +import org.eclipse.sirius.web.services.api.document.RewriteProxiesInput; +import org.eclipse.sirius.web.services.api.document.RewriteProxiesSuccessPayload; +import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.springframework.stereotype.Service; + +import reactor.core.publisher.Sinks.Many; +import reactor.core.publisher.Sinks.One; + +/** + * The event handler to rewrite broken proxy URIs in documents (typically after an upload where the newly created + * documents have different ids). + * + * @author pcdavid + */ +@Service +public class RewriteProxiesEventHandler implements IEditingContextEventHandler { + private final IServicesMessageService messageService; + + public RewriteProxiesEventHandler(IServicesMessageService messageService) { + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public boolean canHandle(IEditingContext editingContext, IInput input) { + return input instanceof RewriteProxiesInput; + } + + @Override + public void handle(One payloadSink, Many changeDescriptionSink, IEditingContext editingContext, IInput input) { + IPayload payload = new ErrorPayload(input.getId(), this.messageService.unexpectedError()); + ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, editingContext.getId(), input); + + if (input instanceof RewriteProxiesInput && editingContext instanceof EditingContext) { + RewriteProxiesInput rewriteInput = (RewriteProxiesInput) input; + AdapterFactoryEditingDomain adapterFactoryEditingDomain = ((EditingContext) editingContext).getDomain(); + int totalRewrittenCount = 0; + for (Resource resource : adapterFactoryEditingDomain.getResourceSet().getResources()) { + totalRewrittenCount += this.rewriteProxyURIs(resource, rewriteInput.getOldDocumentIdToNewDocumentId()); + } + if (totalRewrittenCount > 0) { + changeDescription = new ChangeDescription(ChangeKind.SEMANTIC_CHANGE, editingContext.getId(), input); + } + payload = new RewriteProxiesSuccessPayload(input.getId()); + } + + payloadSink.tryEmitValue(payload); + changeDescriptionSink.tryEmitNext(changeDescription); + } + + private int rewriteProxyURIs(Resource resource, Map oldDocumentIdToNewDocumentId) { + AtomicInteger rewrittenCount = new AtomicInteger(); + resource.getAllContents().forEachRemaining(eObject -> { + eObject.eCrossReferences().forEach(target -> { + InternalEObject internalEObject = (InternalEObject) target; + if (internalEObject.eIsProxy()) { + URI proxyURI = internalEObject.eProxyURI(); + String oldDocumentId = proxyURI.path().substring(1); + String newDocumentId = oldDocumentIdToNewDocumentId.get(oldDocumentId); + if (newDocumentId != null) { + String prefix = EditingContext.RESOURCE_SCHEME + ":///"; //$NON-NLS-1$ + URI newProxyURI = URI.createURI(proxyURI.toString().replace(prefix + oldDocumentId, prefix + newDocumentId)); + internalEObject.eSetProxyURI(newProxyURI); + rewrittenCount.incrementAndGet(); + } + } + }); + }); + return rewrittenCount.get(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/UploadDocumentEventHandler.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/UploadDocumentEventHandler.java index c3ac9fa0ad..1b83e0a3cd 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/UploadDocumentEventHandler.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/documents/UploadDocumentEventHandler.java @@ -21,15 +21,19 @@ import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.stream.StreamSupport; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; 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.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.sirius.components.collaborative.api.ChangeDescription; @@ -41,7 +45,7 @@ import org.eclipse.sirius.components.core.api.IInput; import org.eclipse.sirius.components.core.api.IPayload; import org.eclipse.sirius.components.emf.services.EditingContext; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.components.emf.utils.EMFResourceUtils; import org.eclipse.sirius.components.graphql.api.UploadFile; import org.eclipse.sirius.emfjson.resource.JsonResource; @@ -116,20 +120,20 @@ public void handle(One payloadSink, Many changeDesc if (optionalEditingDomain.isPresent()) { AdapterFactoryEditingDomain adapterFactoryEditingDomain = optionalEditingDomain.get(); - String content = this.getContent(adapterFactoryEditingDomain.getResourceSet().getPackageRegistry(), file); - var optionalDocument = this.documentService.createDocument(projectId, name, content); + Optional contentOpt = this.getContent(adapterFactoryEditingDomain.getResourceSet().getPackageRegistry(), file, uploadDocumentInput.isCheckProxies()); + var optionalDocument = contentOpt.flatMap(content -> this.documentService.createDocument(projectId, name, content)); if (optionalDocument.isPresent()) { Document document = optionalDocument.get(); ResourceSet resourceSet = adapterFactoryEditingDomain.getResourceSet(); - URI uri = URI.createURI(document.getId().toString()); + URI uri = new JSONResourceFactory().createResourceURI(document.getId().toString()); if (resourceSet.getResource(uri, false) == null) { ResourceSet loadingResourceSet = new ResourceSetImpl(); loadingResourceSet.setPackageRegistry(resourceSet.getPackageRegistry()); - JsonResource resource = new SiriusWebJSONResourceFactoryImpl().createResource(uri); + JsonResource resource = new JSONResourceFactory().createResource(uri); loadingResourceSet.getResources().add(resource); try (var inputStream = new ByteArrayInputStream(document.getContent().getBytes())) { resource.load(inputStream, null); @@ -151,29 +155,34 @@ public void handle(One payloadSink, Many changeDesc changeDescriptionSink.tryEmitNext(changeDescription); } - private String getContent(EPackage.Registry registry, UploadFile file) { - String uri = file.getName(); - String content = ""; //$NON-NLS-1$ + private Optional getContent(EPackage.Registry registry, UploadFile file, boolean checkProxies) { + String fileName = file.getName(); + Optional content = Optional.empty(); ResourceSet resourceSet = new ResourceSetImpl(); resourceSet.setPackageRegistry(registry); try (var inputStream = file.getInputStream()) { - URI resourceURI = URI.createURI(uri); + URI resourceURI = new JSONResourceFactory().createResourceURI(fileName); Optional optionalInputResource = this.getResource(inputStream, resourceURI, resourceSet); if (optionalInputResource.isPresent()) { Resource inputResource = optionalInputResource.get(); - JsonResource ouputResource = new SiriusWebJSONResourceFactoryImpl().createResource(URI.createURI(uri)); - resourceSet.getResources().add(ouputResource); - ouputResource.getContents().addAll(inputResource.getContents()); - try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { - Map saveOptions = new HashMap<>(); - saveOptions.put(JsonResource.OPTION_ENCODING, JsonResource.ENCODING_UTF_8); - saveOptions.put(JsonResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); - saveOptions.put(JsonResource.OPTION_ID_MANAGER, new EObjectRandomIDManager()); + if (checkProxies && this.containsProxies(inputResource)) { + this.logger.warn("The resource {} contains unresolvable proxies and will not be uploaded.", fileName); //$NON-NLS-1$ + } else { + JsonResource ouputResource = new JSONResourceFactory().createResourceFromPath(fileName); + resourceSet.getResources().add(ouputResource); + ouputResource.getContents().addAll(inputResource.getContents()); - ouputResource.save(outputStream, saveOptions); + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + Map saveOptions = new HashMap<>(); + saveOptions.put(JsonResource.OPTION_ENCODING, JsonResource.ENCODING_UTF_8); + saveOptions.put(JsonResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); + saveOptions.put(JsonResource.OPTION_ID_MANAGER, new EObjectRandomIDManager()); - content = outputStream.toString(); + ouputResource.save(outputStream, saveOptions); + + content = Optional.of(outputStream.toString()); + } } } } catch (IOException exception) { @@ -182,6 +191,41 @@ private String getContent(EPackage.Registry registry, UploadFile file) { return content; } + private boolean containsProxies(Resource resource) { + + Iterable iterable = () -> EcoreUtil.getAllProperContents(resource, false); + // @formatter:off + boolean resourceContainsAProxy = StreamSupport.stream(iterable.spliterator(), false) + .filter(eObject -> { + boolean eObjectcontainsAProxy = eObject.eClass().getEAllReferences().stream() + .filter(ref -> !ref.isContainment() && eObject.eIsSet(ref)) + .filter(ref -> { + boolean containsAProxy = false; + Object value = eObject.eGet(ref); + if (ref.isMany()) { + List list = (List) value; + containsAProxy = list.stream() + .filter(EObject.class::isInstance) + .map(EObject.class::cast) + .filter(EObject::eIsProxy) + .findFirst() + .isPresent(); + } else { + containsAProxy = ((EObject) value).eIsProxy(); + } + return containsAProxy; + }) + .findFirst() + .isPresent(); + + return eObjectcontainsAProxy; + }) + .findFirst() + .isPresent(); + // @formatter:on + return resourceContainsAProxy; + } + /** * Returns the {@link Resource} with the given {@link URI} or {@link Optional#empty()} regarding to the content of * the first line of the given {@link InputStream}. @@ -208,7 +252,7 @@ private Optional getResource(InputStream inputStream, URI resourceURI, Map options = new HashMap<>(); if (line != null) { if (line.contains("{")) { //$NON-NLS-1$ - resource = new SiriusWebJSONResourceFactoryImpl().createResource(resourceURI); + resource = new JSONResourceFactory().createResource(resourceURI); } else if (line.contains("<")) { //$NON-NLS-1$ resource = new XMIResourceImpl(resourceURI); options = new EMFResourceUtils().getXMILoadOptions(); diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingContextEPackageService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingContextEPackageService.java index 68a8a39b25..93417f68f2 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingContextEPackageService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingContextEPackageService.java @@ -21,7 +21,6 @@ import java.util.function.Function; import java.util.stream.Stream; -import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.impl.EPackageRegistryImpl; import org.eclipse.emf.ecore.resource.Resource; @@ -31,7 +30,7 @@ import org.eclipse.sirius.components.domain.DomainPackage; import org.eclipse.sirius.components.domain.emf.DomainConverter; import org.eclipse.sirius.components.emf.services.IEditingContextEPackageService; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.eclipse.sirius.web.persistence.entities.DocumentEntity; import org.eclipse.sirius.web.persistence.repositories.IDocumentRepository; @@ -111,8 +110,7 @@ private Stream findDynamicEPackages(Function persist(EditingDomain editingDomain) { List result = new ArrayList<>(); - List resources = editingDomain.getResourceSet().getResources(); + + // @formatter:off + List resources = editingDomain.getResourceSet().getResources().stream() + .filter(res -> { + if (res.getURI() != null) { + return EditingContext.RESOURCE_SCHEME.equals(res.getURI().scheme()); + } + return false; + }) + .collect(Collectors.toList()); + // @formatter:on + for (Resource resource : resources) { this.save(resource).ifPresent(result::add); } @@ -115,7 +126,7 @@ private Optional save(Resource resource) { String content = new String(bytes); // @formatter:off - result = new IDParser().parse(resource.getURI().toString()) + result = new IDParser().parse(resource.getURI().path().substring(1)) .flatMap(this.documentRepository::findById) .map(entity -> { entity.setContent(content); diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingContextSearchService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingContextSearchService.java index f2ac37e45f..30550dc129 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingContextSearchService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingContextSearchService.java @@ -19,20 +19,14 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; -import org.eclipse.emf.common.command.BasicCommandStack; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.impl.EPackageRegistryImpl; +import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; -import org.eclipse.emf.edit.provider.ComposedAdapterFactory; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IEditingContextSearchService; import org.eclipse.sirius.components.emf.services.EditingContext; -import org.eclipse.sirius.components.emf.services.IEditingContextEPackageService; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; -import org.eclipse.sirius.emfjson.resource.JsonResource; +import org.eclipse.sirius.components.emf.services.EditingContextCrossReferenceAdapter; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.web.persistence.entities.DocumentEntity; import org.eclipse.sirius.web.persistence.repositories.IDocumentRepository; import org.eclipse.sirius.web.persistence.repositories.IProjectRepository; @@ -62,21 +56,15 @@ public class EditingContextSearchService implements IEditingContextSearchService private final IDocumentRepository documentRepository; - private final IEditingContextEPackageService editingContextEPackageService; - - private final ComposedAdapterFactory composedAdapterFactory; - - private final EPackage.Registry globalEPackageRegistry; + private final EditingDomainFactoryService editingDomainFactoryService; private final Timer timer; - public EditingContextSearchService(IProjectRepository projectRepository, IDocumentRepository documentRepository, IEditingContextEPackageService editingContextEPackageService, - ComposedAdapterFactory composedAdapterFactory, EPackage.Registry globalEPackageRegistry, MeterRegistry meterRegistry) { + public EditingContextSearchService(IProjectRepository projectRepository, IDocumentRepository documentRepository, EditingDomainFactoryService editingDomainFactoryService, + MeterRegistry meterRegistry) { this.projectRepository = Objects.requireNonNull(projectRepository); this.documentRepository = Objects.requireNonNull(documentRepository); - this.editingContextEPackageService = Objects.requireNonNull(editingContextEPackageService); - this.composedAdapterFactory = Objects.requireNonNull(composedAdapterFactory); - this.globalEPackageRegistry = Objects.requireNonNull(globalEPackageRegistry); + this.editingDomainFactoryService = Objects.requireNonNull(editingDomainFactoryService); this.timer = Timer.builder(TIMER_NAME).register(meterRegistry); } @@ -93,20 +81,13 @@ public Optional findById(String editingContextId) { this.logger.debug("Loading the editing context {}", editingContextId); //$NON-NLS-1$ - AdapterFactoryEditingDomain editingDomain = new AdapterFactoryEditingDomain(this.composedAdapterFactory, new BasicCommandStack()); + AdapterFactoryEditingDomain editingDomain = this.editingDomainFactoryService.createEditingDomain(editingContextId); ResourceSet resourceSet = editingDomain.getResourceSet(); - resourceSet.eAdapters().add(new ECrossReferenceAdapter()); - - EPackageRegistryImpl ePackageRegistry = new EPackageRegistryImpl(); - this.globalEPackageRegistry.forEach(ePackageRegistry::put); - List additionalEPackages = this.editingContextEPackageService.getEPackages(editingContextId); - additionalEPackages.forEach(ePackage -> ePackageRegistry.put(ePackage.getNsURI(), ePackage)); - resourceSet.setPackageRegistry(ePackageRegistry); List documentEntities = new IDParser().parse(editingContextId).map(this.documentRepository::findAllByProjectId).orElseGet(List::of); for (DocumentEntity documentEntity : documentEntities) { - URI uri = URI.createURI(documentEntity.getId().toString()); - JsonResource resource = new SiriusWebJSONResourceFactoryImpl().createResource(uri); + Resource resource = new JSONResourceFactory().createResourceFromPath(documentEntity.getId().toString()); + try (var inputStream = new ByteArrayInputStream(documentEntity.getContent().getBytes())) { resourceSet.getResources().add(resource); resource.load(inputStream, null); @@ -118,6 +99,10 @@ public Optional findById(String editingContextId) { } } + // The ECrossReferenceAdapter must be set after the resource loading because it needs to resolve proxies in case + // of inter-resources references + resourceSet.eAdapters().add(new EditingContextCrossReferenceAdapter()); + this.logger.debug("{} documents loaded for the editing context {}", resourceSet.getResources().size(), editingContextId); //$NON-NLS-1$ long end = System.currentTimeMillis(); diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingDomainFactoryService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingDomainFactoryService.java new file mode 100644 index 0000000000..b4f5b24924 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/editingcontext/EditingDomainFactoryService.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2022 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 java.util.Optional; + +import org.eclipse.emf.common.command.BasicCommandStack; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.impl.EPackageRegistryImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.Resource.Factory.Registry; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.sirius.components.emf.services.IEditingContextEPackageService; +import org.springframework.stereotype.Service; + +/** + * This class is used to create the editing domain used as editing context.
+ * It instantiates the ResourceSet with the right configuration. + * + * @author lfasani + */ +@Service +public class EditingDomainFactoryService { + + private final IEditingContextEPackageService editingContextEPackageService; + + private final ComposedAdapterFactory composedAdapterFactory; + + private final EPackage.Registry globalEPackageRegistry; + + private final Optional resourceFactoryRegistryOpt; + + public EditingDomainFactoryService(IEditingContextEPackageService editingContextEPackageService, ComposedAdapterFactory composedAdapterFactory, EPackage.Registry globalEPackageRegistry, + Optional resourceFactoryRegistryOpt) { + this.editingContextEPackageService = Objects.requireNonNull(editingContextEPackageService); + this.composedAdapterFactory = Objects.requireNonNull(composedAdapterFactory); + this.globalEPackageRegistry = Objects.requireNonNull(globalEPackageRegistry); + this.resourceFactoryRegistryOpt = resourceFactoryRegistryOpt; + } + + public AdapterFactoryEditingDomain createEditingDomain(String editingContextId) { + AdapterFactoryEditingDomain editingDomain = new AdapterFactoryEditingDomain(this.composedAdapterFactory, new BasicCommandStack()); + ResourceSet resourceSet = editingDomain.getResourceSet(); + + EPackageRegistryImpl ePackageRegistry = new EPackageRegistryImpl(); + this.globalEPackageRegistry.forEach(ePackageRegistry::put); + List additionalEPackages = this.editingContextEPackageService.getEPackages(editingContextId); + additionalEPackages.forEach(ePackage -> ePackageRegistry.put(ePackage.getNsURI(), ePackage)); + resourceSet.setPackageRegistry(ePackageRegistry); + + if (this.resourceFactoryRegistryOpt.isPresent()) { + resourceSet.setResourceFactoryRegistry(this.resourceFactoryRegistryOpt.get()); + } + + return editingDomain; + } +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/DeleteDocumentTreeItemEventHandler.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/DeleteDocumentTreeItemEventHandler.java index 7f15e24c91..3e761c6f27 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/DeleteDocumentTreeItemEventHandler.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/DeleteDocumentTreeItemEventHandler.java @@ -25,6 +25,7 @@ import org.eclipse.sirius.components.collaborative.api.ChangeKind; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.emf.services.EditingContext; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.components.representations.Failure; import org.eclipse.sirius.components.representations.IStatus; import org.eclipse.sirius.components.representations.Success; @@ -69,7 +70,7 @@ public IStatus handle(IEditingContext editingContext, TreeItem treeItem) { DocumentEntity documentEntity = optionalDocumentEntity.get(); ResourceSet resourceSet = editingDomain.getResourceSet(); - URI uri = URI.createURI(documentEntity.getId().toString()); + URI uri = new JSONResourceFactory().createResourceURI(documentEntity.getId().toString()); // @formatter:off List resourcesToDelete = resourceSet.getResources().stream() diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/ExplorerDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/ExplorerDescriptionProvider.java index a18a0aa852..d02ce6da6f 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/ExplorerDescriptionProvider.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/ExplorerDescriptionProvider.java @@ -113,7 +113,7 @@ private String getTreeItemId(VariableManager variableManager) { id = ((RepresentationMetadata) self).getId(); } else if (self instanceof Resource) { Resource resource = (Resource) self; - id = resource.getURI().toString(); + id = resource.getURI().path().substring(1); } else if (self instanceof EObject) { id = this.objectService.getId(self); } @@ -201,7 +201,7 @@ private String getImageURL(VariableManager variableManager) { return Optional.ofNullable(imageURL).orElse(ImageConstants.DEFAULT_SVG); } - private List getElements(VariableManager variableManager) { + private List getElements(VariableManager variableManager) { var optionalEditingContext = Optional.of(variableManager.getVariables().get(IEditingContext.EDITING_CONTEXT)); // @formatter:off var optionalResourceSet = optionalEditingContext.filter(IEditingContext.class::isInstance) @@ -209,11 +209,19 @@ private List getElements(VariableManager variableManager) { .map(EditingContext.class::cast) .map(EditingContext::getDomain) .map(EditingDomain::getResourceSet); - // @formatter:on if (optionalResourceSet.isPresent()) { var resourceSet = optionalResourceSet.get(); - return new ArrayList<>(resourceSet.getResources()); + List resources = resourceSet.getResources().stream() + .filter(res -> { + if (res.getURI() != null) { + return EditingContext.RESOURCE_SCHEME.equals(res.getURI().scheme()); + } + return false; + }) + .collect(Collectors.toList()); + // @formatter:on + return resources; } return new ArrayList<>(); } diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/ExplorerTreePathProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/ExplorerTreePathProvider.java index 7295a99637..94f3bed9e0 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/ExplorerTreePathProvider.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/ExplorerTreePathProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021, 2022 Obeo. + * Copyright (c) 2022 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 @@ -10,7 +10,6 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ - package org.eclipse.sirius.web.services.explorer; import java.util.ArrayList; @@ -109,7 +108,7 @@ private String getItemId(Object object) { String result = null; if (object instanceof Resource) { Resource resource = (Resource) object; - result = resource.getURI().toString(); + result = resource.getURI().path().substring(1); } else if (object instanceof EObject) { result = this.objectService.getId(object); } diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/RenameDocumentTreeItemHandler.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/RenameDocumentTreeItemHandler.java index 222a67c9f7..737f271e55 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/RenameDocumentTreeItemHandler.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/explorer/RenameDocumentTreeItemHandler.java @@ -71,7 +71,7 @@ public IStatus handle(IEditingContext editingContext, TreeItem treeItem, String // @formatter:off resourceSet.getResources().stream() - .filter(resource -> documentEntity.getId().toString().equals(resource.getURI().toString())) + .filter(resource -> documentEntity.getId().toString().equals(resource.getURI().path().substring(1))) .findFirst() .ifPresent(resource -> { resource.eAdapters().stream() diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/projects/ProjectExportService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/projects/ProjectExportService.java index 70ce621d83..6ddb75f0cc 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/projects/ProjectExportService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/projects/ProjectExportService.java @@ -27,7 +27,6 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.impl.EPackageRegistryImpl; @@ -36,7 +35,7 @@ import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.sirius.components.emf.services.IEditingContextEPackageService; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.components.representations.IRepresentation; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.eclipse.sirius.emfjson.resource.JsonResourceFactoryImpl; @@ -282,8 +281,7 @@ private ResourceSet loadAllDocuments(String projectId) { for (Document document : documents) { ResourceSet loadingResourceSet = new ResourceSetImpl(); loadingResourceSet.setPackageRegistry(ePackageRegistry); - URI uri = URI.createURI(document.getId().toString()); - JsonResource resource = new SiriusWebJSONResourceFactoryImpl().createResource(uri); + JsonResource resource = new JSONResourceFactory().createResourceFromPath(document.getId().toString()); loadingResourceSet.getResources().add(resource); Optional optionalBytes = this.documentService.getBytes(document, IDocumentService.RESOURCE_KIND_JSON); if (optionalBytes.isPresent()) { diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/projects/ProjectImporter.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/projects/ProjectImporter.java index c2c843eb96..158d0583e7 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/projects/ProjectImporter.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/projects/ProjectImporter.java @@ -28,6 +28,7 @@ import org.eclipse.sirius.web.persistence.entities.IdMappingEntity; import org.eclipse.sirius.web.persistence.repositories.IIdMappingRepository; import org.eclipse.sirius.web.services.api.document.Document; +import org.eclipse.sirius.web.services.api.document.RewriteProxiesInput; import org.eclipse.sirius.web.services.api.document.UploadDocumentInput; import org.eclipse.sirius.web.services.api.document.UploadDocumentSuccessPayload; import org.eclipse.sirius.web.services.api.projects.ProjectManifest; @@ -96,7 +97,7 @@ private boolean createRepresentations(UUID inputId) { RepresentationManifest representationManifest = this.projectManifest.getRepresentations().get(representationDescriptor.getId().toString()); String targetObjectURI = representationManifest.getTargetObjectURI(); - String oldDocumentId = URI.create(targetObjectURI).getPath(); + String oldDocumentId = URI.create(targetObjectURI).getPath().substring(1); Document newDocument = this.oldDocumentIdToNewDocument.get(oldDocumentId); final String objectId; if (newDocument != null) { @@ -149,7 +150,7 @@ private boolean createDocuments(UUID inputId) { for (Entry entry : this.documents.entrySet()) { String oldDocumentId = entry.getKey(); UploadFile uploadFile = entry.getValue(); - UploadDocumentInput input = new UploadDocumentInput(inputId, this.projectId, uploadFile); + UploadDocumentInput input = new UploadDocumentInput(inputId, this.projectId, uploadFile, false); // @formatter:off Document document = this.editingContextEventProcessor.handle(input) @@ -165,6 +166,13 @@ private boolean createDocuments(UUID inputId) { this.oldDocumentIdToNewDocument.put(oldDocumentId, document); } + Map documentIds = new HashMap<>(); + for (Map.Entry entry : this.oldDocumentIdToNewDocument.entrySet()) { + documentIds.put(entry.getKey(), entry.getValue().getId().toString()); + } + RewriteProxiesInput rewriteInput = new RewriteProxiesInput(UUID.randomUUID(), this.editingContextEventProcessor.getEditingContextId(), documentIds); + this.editingContextEventProcessor.handle(rewriteInput).blockOptional(); + return this.oldDocumentIdToNewDocument.values().stream().allMatch(Objects::nonNull); } diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/DynamicRepresentationDescriptionService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/DynamicRepresentationDescriptionService.java index 62a261715c..a19c07946e 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/DynamicRepresentationDescriptionService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/DynamicRepresentationDescriptionService.java @@ -20,7 +20,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EPackage.Registry; import org.eclipse.emf.ecore.resource.Resource; @@ -28,7 +27,7 @@ import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.emf.services.EditingContext; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +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.ViewPackage; @@ -105,8 +104,8 @@ private Stream getViewDefinitions(Resource resource) { private Resource loadDocumentAsEMF(DocumentEntity documentEntity) { ResourceSet resourceSet = new ResourceSetImpl(); resourceSet.setPackageRegistry(this.ePackageRegistry); - URI uri = URI.createURI(documentEntity.getId().toString()); - JsonResource resource = new SiriusWebJSONResourceFactoryImpl().createResource(uri); + + JsonResource resource = new JSONResourceFactory().createResourceFromPath(documentEntity.getId().toString()); resourceSet.getResources().add(resource); try (var inputStream = new ByteArrayInputStream(documentEntity.getContent().getBytes())) { resource.load(inputStream, null); diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/ViewService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/ViewService.java index 2051652e1b..31c1fa8f7f 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/ViewService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/representations/ViewService.java @@ -19,14 +19,13 @@ import java.util.UUID; import java.util.stream.Stream; -import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; 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.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.components.view.RepresentationDescription; import org.eclipse.sirius.components.view.View; import org.eclipse.sirius.components.view.ViewPackage; @@ -80,9 +79,10 @@ public Optional getRepresentationDescription(String r private Resource loadDocumentAsEMF(DocumentEntity documentEntity) { ResourceSet resourceSet = new ResourceSetImpl(); resourceSet.setPackageRegistry(this.ePackageRegistry); - URI uri = URI.createURI(documentEntity.getId().toString()); - JsonResource resource = new SiriusWebJSONResourceFactoryImpl().createResource(uri); + + JsonResource resource = new JSONResourceFactory().createResourceFromPath(documentEntity.getId().toString()); resourceSet.getResources().add(resource); + try (var inputStream = new ByteArrayInputStream(documentEntity.getContent().getBytes())) { resource.load(inputStream, null); } catch (IOException | IllegalArgumentException exception) { diff --git a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/DeleteDocumentEventHandlerTests.java b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/DeleteDocumentEventHandlerTests.java index 0cd2436854..c41bd0ebdd 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/DeleteDocumentEventHandlerTests.java +++ b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/DeleteDocumentEventHandlerTests.java @@ -17,7 +17,6 @@ import java.util.Optional; import java.util.UUID; -import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.sirius.components.collaborative.api.ChangeDescription; @@ -26,7 +25,7 @@ import org.eclipse.sirius.components.collaborative.dto.DeleteDocumentSuccessPayload; import org.eclipse.sirius.components.core.api.IPayload; import org.eclipse.sirius.components.emf.services.EditingContext; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.web.services.api.accounts.Profile; import org.eclipse.sirius.web.services.api.document.Document; import org.eclipse.sirius.web.services.api.document.IDocumentService; @@ -63,7 +62,7 @@ public Optional getDocument(UUID documentId) { AdapterFactoryEditingDomain editingDomain = new EditingDomainFactory().create(); - Resource resource = new SiriusWebJSONResourceFactoryImpl().createResource(URI.createURI(document.getId().toString())); + Resource resource = new JSONResourceFactory().createResourceFromPath(document.getId().toString()); editingDomain.getResourceSet().getResources().add(resource); EditingContext editingContext = new EditingContext(UUID.randomUUID().toString(), editingDomain); diff --git a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/RenameDocumentEventHandlerTests.java b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/RenameDocumentEventHandlerTests.java index ae131cc70b..7e0c6719b8 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/RenameDocumentEventHandlerTests.java +++ b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/RenameDocumentEventHandlerTests.java @@ -17,7 +17,6 @@ import java.util.Optional; import java.util.UUID; -import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.sirius.components.collaborative.api.ChangeDescription; @@ -28,7 +27,7 @@ import org.eclipse.sirius.components.core.api.IInput; import org.eclipse.sirius.components.core.api.IPayload; import org.eclipse.sirius.components.emf.services.EditingContext; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.web.services.api.accounts.Profile; import org.eclipse.sirius.web.services.api.document.Document; import org.eclipse.sirius.web.services.api.document.IDocumentService; @@ -68,7 +67,7 @@ public Optional rename(UUID documentId, String newName) { AdapterFactoryEditingDomain editingDomain = new EditingDomainFactory().create(); DocumentMetadataAdapter adapter = new DocumentMetadataAdapter(OLD_NAME); - Resource resource = new SiriusWebJSONResourceFactoryImpl().createResource(URI.createURI(documentId.toString())); + Resource resource = new JSONResourceFactory().createResourceFromPath(documentId.toString()); resource.eAdapters().add(adapter); editingDomain.getResourceSet().getResources().add(resource); diff --git a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/UploadDocumentEventHandlerTests.java b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/UploadDocumentEventHandlerTests.java index 843c17f089..8adbb3f2a4 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/UploadDocumentEventHandlerTests.java +++ b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/documents/UploadDocumentEventHandlerTests.java @@ -31,7 +31,6 @@ import java.util.Optional; import java.util.UUID; -import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.Resource; @@ -39,11 +38,12 @@ import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.sirius.components.collaborative.api.ChangeDescription; import org.eclipse.sirius.components.collaborative.api.ChangeKind; +import org.eclipse.sirius.components.core.api.ErrorPayload; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IPayload; import org.eclipse.sirius.components.emf.services.EObjectIDManager; import org.eclipse.sirius.components.emf.services.EditingContext; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.components.graphql.api.UploadFile; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.eclipse.sirius.emfjson.resource.JsonResourceImpl; @@ -116,7 +116,7 @@ public class UploadDocumentEventHandlerTests { @Test public void testUploadXMIDocument() { - EditingDomain editingDomain = this.uploadDocument(XMI_CONTENT.getBytes()); + EditingDomain editingDomain = this.uploadDocument(new ByteArrayInputStream(XMI_CONTENT.getBytes()), ChangeKind.SEMANTIC_CHANGE, UploadDocumentSuccessPayload.class); this.testUploadXMIDocument(editingDomain); } @@ -141,27 +141,21 @@ private void testUploadXMIDocument(EditingDomain editingDomain) { @Test public void testUploadEmptyDocument() { - EditingDomain editingDomain = this.uploadDocument(new byte[0]); - assertThat(editingDomain.getResourceSet().getResources().size()).isEqualTo(1); - Resource res = editingDomain.getResourceSet().getResources().get(0); - assertThat(res).isInstanceOf(JsonResourceImpl.class); - assertThat(res.getContents()).hasSize(0); - } + EditingDomain editingDomain = this.uploadDocument(new ByteArrayInputStream(new byte[0]), ChangeKind.NOTHING, ErrorPayload.class); - private EditingDomain uploadDocument(byte[] contents) { - return this.uploadDocument(new ByteArrayInputStream(contents)); + assertThat(editingDomain.getResourceSet().getResources().size()).isEqualTo(0); } private EditingDomain uploadDocument(File file) { try { - return this.uploadDocument(new FileInputStream(file)); + return this.uploadDocument(new FileInputStream(file), ChangeKind.SEMANTIC_CHANGE, UploadDocumentSuccessPayload.class); } catch (FileNotFoundException exception) { fail(exception.getMessage()); } return null; } - private EditingDomain uploadDocument(InputStream inputstream) { + private EditingDomain uploadDocument(InputStream inputstream, String expectedChangeKind, Class expectedPayload) { IDocumentService documentService = new IDocumentService.NoOp() { @Override public Optional createDocument(String projectId, String name, String content) { @@ -173,7 +167,7 @@ public Optional createDocument(String projectId, String name, String c UploadDocumentEventHandler handler = new UploadDocumentEventHandler(documentService, messageService, new SimpleMeterRegistry()); UploadFile file = new UploadFile(FILE_NAME, inputstream); - var input = new UploadDocumentInput(UUID.randomUUID(), UUID.randomUUID().toString(), file); + var input = new UploadDocumentInput(UUID.randomUUID(), UUID.randomUUID().toString(), file, false); AdapterFactoryEditingDomain editingDomain = new EditingDomainFactory().create(); @@ -186,10 +180,10 @@ public Optional createDocument(String projectId, String name, String c handler.handle(payloadSink, changeDescriptionSink, editingContext, input); ChangeDescription changeDescription = changeDescriptionSink.asFlux().blockFirst(); - assertThat(changeDescription.getKind()).isEqualTo(ChangeKind.SEMANTIC_CHANGE); + assertThat(changeDescription.getKind()).isEqualTo(expectedChangeKind); IPayload payload = payloadSink.asMono().block(); - assertThat(payload).isInstanceOf(UploadDocumentSuccessPayload.class); + assertThat(payload).isInstanceOf(expectedPayload); return editingDomain; } @@ -208,7 +202,7 @@ public void testEObjectIDGenerationForUpload() { final UUID documentId = UUID.randomUUID(); this.simulatesDocumentUpload(editingDomain, documentId, resourceBytes); - Resource resource = editingDomain.getResourceSet().getResource(URI.createURI(documentId.toString()), false); + Resource resource = editingDomain.getResourceSet().getResource(new JSONResourceFactory().createResourceURI(documentId.toString()), false); // Use an output stream to prevent the resource to be written on file system. try (var outputStream = new ByteArrayOutputStream()) { resource.save(outputStream, Collections.singletonMap(JsonResource.OPTION_ID_MANAGER, new EObjectIDManager() { @@ -252,7 +246,7 @@ public Optional createDocument(String projectId, String name, String c UploadDocumentEventHandler handler = new UploadDocumentEventHandler(documentService, messageService, new SimpleMeterRegistry()); UploadFile file = new UploadFile(FILE_NAME, new ByteArrayInputStream(resourceBytes)); - var input = new UploadDocumentInput(UUID.randomUUID(), UUID.randomUUID().toString(), file); + var input = new UploadDocumentInput(UUID.randomUUID(), UUID.randomUUID().toString(), file, false); IEditingContext editingContext = new EditingContext(UUID.randomUUID().toString(), editingDomain); @@ -275,7 +269,7 @@ public Optional createDocument(String projectId, String name, String c */ private Map getEObjectUriToId(EditingDomain editingDomain, byte[] resourceBytes) { Map eObjectUriToId = new HashMap<>(); - JsonResource jsonResource = new SiriusWebJSONResourceFactoryImpl().createResource(URI.createURI("json.flow")); //$NON-NLS-1$ + JsonResource jsonResource = new JSONResourceFactory().createResourceFromPath("json.flow"); //$NON-NLS-1$ editingDomain.getResourceSet().getResources().add(jsonResource); Map options = new HashMap<>(); diff --git a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/editingcontext/EditingContextPersistenceServiceTests.java b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/editingcontext/EditingContextPersistenceServiceTests.java index 56f09d6f65..c741d8b0fc 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/editingcontext/EditingContextPersistenceServiceTests.java +++ b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/editingcontext/EditingContextPersistenceServiceTests.java @@ -19,14 +19,13 @@ import java.util.Optional; import java.util.UUID; -import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IEditingContextPersistenceService; import org.eclipse.sirius.components.emf.services.EditingContext; -import org.eclipse.sirius.components.emf.services.SiriusWebJSONResourceFactoryImpl; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.eclipse.sirius.web.persistence.entities.AccountEntity; import org.eclipse.sirius.web.persistence.entities.DocumentEntity; @@ -50,7 +49,7 @@ public void testDocumentPersistence() { String name = "New Document"; //$NON-NLS-1$ UUID id = UUID.randomUUID(); - JsonResource resource = new SiriusWebJSONResourceFactoryImpl().createResource(URI.createURI(id.toString())); + JsonResource resource = new JSONResourceFactory().createResourceFromPath(id.toString()); resource.eAdapters().add(new DocumentMetadataAdapter(name)); EClass eClass = EcoreFactory.eINSTANCE.createEClass(); diff --git a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/editingcontext/EditingContextSearchServiceTests.java b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/editingcontext/EditingContextSearchServiceTests.java index 4e2d1ef4e5..6f5f0de540 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/editingcontext/EditingContextSearchServiceTests.java +++ b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/editingcontext/EditingContextSearchServiceTests.java @@ -15,9 +15,9 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.List; +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; @@ -29,6 +29,7 @@ import org.eclipse.sirius.components.core.api.IEditingContextSearchService; import org.eclipse.sirius.components.emf.services.EditingContext; import org.eclipse.sirius.components.emf.services.IEditingContextEPackageService; +import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.web.persistence.entities.DocumentEntity; import org.eclipse.sirius.web.persistence.entities.ProjectEntity; import org.eclipse.sirius.web.persistence.repositories.IDocumentRepository; @@ -85,8 +86,9 @@ public void testEditingContextWithNoDocuments() { String projectId = UUID.randomUUID().toString(); IEditingContextEPackageService editingContextEPackageService = editingContextId -> List.of(); - IEditingContextSearchService editingContextSearchService = new EditingContextSearchService(projectRepository, documentRepository, editingContextEPackageService, composedAdapterFactory, - ePackageRegistry, new SimpleMeterRegistry()); + + EditingDomainFactoryService editingDomainFactoryService = new EditingDomainFactoryService(editingContextEPackageService, composedAdapterFactory, ePackageRegistry, Optional.empty()); + IEditingContextSearchService editingContextSearchService = new EditingContextSearchService(projectRepository, documentRepository, editingDomainFactoryService, new SimpleMeterRegistry()); IEditingContext editingContext = editingContextSearchService.findById(projectId).get(); assertThat(editingContext).isInstanceOf(EditingContext.class); @@ -127,18 +129,18 @@ public List findAllByProjectId(UUID projectId) { ePackageRegistry.put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE); IEditingContextEPackageService editingContextEPackageService = editingContextId -> List.of(); - IEditingContextSearchService editingContextSearchService = new EditingContextSearchService(projectRepository, documentRepository, editingContextEPackageService, composedAdapterFactory, - ePackageRegistry, new SimpleMeterRegistry()); + EditingDomainFactoryService editingDomainFactoryService = new EditingDomainFactoryService(editingContextEPackageService, composedAdapterFactory, ePackageRegistry, Optional.empty()); + IEditingContextSearchService editingContextSearchService = new EditingContextSearchService(projectRepository, documentRepository, editingDomainFactoryService, new SimpleMeterRegistry()); IEditingContext editingContext = editingContextSearchService.findById(projectId.toString()).get(); assertThat(editingContext).isInstanceOf(EditingContext.class); EditingDomain editingDomain = ((EditingContext) editingContext).getDomain(); assertThat(editingDomain.getResourceSet().getResources()).hasSize(2); - Resource firstResource = editingDomain.getResourceSet().getResource(URI.createURI(firstDocumentEntity.getId().toString()), true); + Resource firstResource = editingDomain.getResourceSet().getResource(new JSONResourceFactory().createResourceURI(firstDocumentEntity.getId().toString()), true); this.assertProperResourceLoading(firstResource, firstDocumentEntity); - Resource secondResource = editingDomain.getResourceSet().getResource(URI.createURI(secondDocumentEntity.getId().toString()), true); + Resource secondResource = editingDomain.getResourceSet().getResource(new JSONResourceFactory().createResourceURI(secondDocumentEntity.getId().toString()), true); this.assertProperResourceLoading(secondResource, secondDocumentEntity); }