diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 31f11eef3a..6478d3abeb 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -56,6 +56,7 @@ In the near future, the GraphQL schema and the frontend of `sirius-components-fo - https://github.com/eclipse-sirius/sirius-web/issues/2371[#2371] [sirius-web] Default colors are now loaded from a default model located in `sirius-components-view/src/main/resources/studioColorPalettes.json`. They are loaded in every studio project but hidden in the explorer. They are also made readonly in the details view. +Applications derived from Sirius Web may have to ensure that references to default colors are properly resolved when loading a view model. - https://github.com/eclipse-sirius/sirius-web/issues/2191[#2191] [view] The Color property on ImageNodeStyle has been removed. === Dependency update @@ -92,6 +93,7 @@ An error message is now displayed if the _Shape_ is not set. - https://github.com/eclipse-sirius/sirius-web/issues/2191[#2191] [view] The Color property on ImageNodeStyle has been removed. - https://github.com/eclipse-sirius/sirius-web/issues/2395[#2395] [vs-code] Fix an issue that appeared while rendering diagram with vs-code extension. - https://github.com/eclipse-sirius/sirius-web/issues/2426[#2426] [sirius-web] Fix an issue where the Representations view was always empty. +- https://github.com/eclipse-sirius/sirius-web/issues/2429[#2429] [sirius-web] Ensure that view models can be successfully uploaded by loading the default color palettes === New Features 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 e18c34a372..24b12f0bec 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 @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.UUID; import java.util.stream.StreamSupport; import org.eclipse.emf.common.util.URI; @@ -55,9 +56,12 @@ import org.eclipse.sirius.web.services.api.document.IDocumentService; 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.Nature; import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.eclipse.sirius.web.services.projects.api.IEditingContextMetadataProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import io.micrometer.core.instrument.Counter; @@ -79,12 +83,15 @@ public class UploadDocumentEventHandler implements IEditingContextEventHandler { private final IServicesMessageService messageService; + private final IEditingContextMetadataProvider editingContextMetadataProvider; + private final Counter counter; - public UploadDocumentEventHandler(IDocumentService documentService, IServicesMessageService messageService, MeterRegistry meterRegistry) { + public UploadDocumentEventHandler(IDocumentService documentService, IServicesMessageService messageService, MeterRegistry meterRegistry, + IEditingContextMetadataProvider editingContextMetadataProvider) { this.documentService = Objects.requireNonNull(documentService); this.messageService = Objects.requireNonNull(messageService); - + this.editingContextMetadataProvider = Objects.requireNonNull(editingContextMetadataProvider); // @formatter:off this.counter = Counter.builder(Monitoring.EVENT_HANDLER) .tag(Monitoring.NAME, this.getClass().getSimpleName()) @@ -104,24 +111,21 @@ public void handle(One payloadSink, Many changeDesc IPayload payload = new ErrorPayload(input.id(), this.messageService.unexpectedError()); ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, editingContext.getId(), input); - if (input instanceof UploadDocumentInput) { + if (input instanceof UploadDocumentInput uploadDocumentInput) { - UploadDocumentInput uploadDocumentInput = (UploadDocumentInput) input; String projectId = uploadDocumentInput.editingContextId(); UploadFile file = uploadDocumentInput.file(); - // @formatter:off Optional optionalEditingDomain = Optional.of(editingContext) .filter(EditingContext.class::isInstance) .map(EditingContext.class::cast) .map(EditingContext::getDomain); - // @formatter:on String name = file.getName().trim(); if (optionalEditingDomain.isPresent()) { AdapterFactoryEditingDomain adapterFactoryEditingDomain = optionalEditingDomain.get(); - Optional contentOpt = this.getContent(adapterFactoryEditingDomain.getResourceSet().getPackageRegistry(), file, uploadDocumentInput.checkProxies()); + Optional contentOpt = this.getContent(adapterFactoryEditingDomain.getResourceSet().getPackageRegistry(), file, uploadDocumentInput.checkProxies(), projectId); var optionalDocument = contentOpt.flatMap(content -> this.documentService.createDocument(projectId, name, content)); if (optionalDocument.isPresent()) { @@ -156,11 +160,16 @@ public void handle(One payloadSink, Many changeDesc changeDescriptionSink.tryEmitNext(changeDescription); } - private Optional getContent(EPackage.Registry registry, UploadFile file, boolean checkProxies) { + private Optional getContent(EPackage.Registry registry, UploadFile file, boolean checkProxies, String editingContextId) { + var isStudioProjectNature = this.editingContextMetadataProvider.getMetadata(editingContextId).natures().stream().map(Nature::natureId) + .anyMatch("siriusComponents://nature?kind=studio"::equals); String fileName = file.getName(); Optional content = Optional.empty(); ResourceSet resourceSet = new ResourceSetImpl(); resourceSet.setPackageRegistry(registry); + if (isStudioProjectNature) { + this.loadStudioColorPalettes(resourceSet); + } try (var inputStream = file.getInputStream()) { URI resourceURI = new JSONResourceFactory().createResourceURI(fileName); Optional optionalInputResource = this.getResource(inputStream, resourceURI, resourceSet); @@ -193,38 +202,24 @@ private Optional getContent(EPackage.Registry registry, UploadFile file, } 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; + return StreamSupport.stream(iterable.spliterator(), false) + .anyMatch(eObject -> eObject.eClass().getEAllReferences().stream() + .filter(ref -> !ref.isContainment() && eObject.eIsSet(ref)) + .anyMatch(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) + .anyMatch(EObject::eIsProxy); + } else if (value instanceof EObject eObjectValue) { + containsAProxy = eObjectValue.eIsProxy(); + } + return containsAProxy; + })); } /** @@ -270,4 +265,18 @@ private Optional getResource(InputStream inputStream, URI resourceURI, return Optional.ofNullable(resource); } + private void loadStudioColorPalettes(ResourceSet resourceSet) { + ClassPathResource classPathResource = new ClassPathResource("studioColorPalettes.json"); + URI uri = URI.createURI(EditingContext.RESOURCE_SCHEME + ":///" + UUID.nameUUIDFromBytes(classPathResource.getPath().getBytes())); + Resource resource = new JSONResourceFactory().createResource(uri); + try (var inputStream = new ByteArrayInputStream(classPathResource.getContentAsByteArray())) { + resourceSet.getResources().add(resource); + resource.load(inputStream, null); + resource.eAdapters().add(new ResourceMetadataAdapter("studioColorPalettes")); + } catch (IOException exception) { + this.logger.warn("An error occured while loading document studioColorPalettes.json: {}.", exception.getMessage()); + resourceSet.getResources().remove(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 a157f88c0f..1a35608fc0 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 @@ -27,6 +27,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -54,6 +55,8 @@ import org.eclipse.sirius.web.services.api.projects.Project; import org.eclipse.sirius.web.services.messages.IServicesMessageService; import org.eclipse.sirius.web.services.projects.NoOpServicesMessageService; +import org.eclipse.sirius.web.services.projects.api.EditingContextMetadata; +import org.eclipse.sirius.web.services.projects.api.IEditingContextMetadataProvider; import org.junit.jupiter.api.Test; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; @@ -163,8 +166,10 @@ public Optional createDocument(String projectId, String name, String c } }; IServicesMessageService messageService = new NoOpServicesMessageService(); + var editingContextMetadata = new EditingContextMetadata(List.of()); + IEditingContextMetadataProvider editingContextMetadataProvider = editingContextId -> editingContextMetadata; - UploadDocumentEventHandler handler = new UploadDocumentEventHandler(documentService, messageService, new SimpleMeterRegistry()); + UploadDocumentEventHandler handler = new UploadDocumentEventHandler(documentService, messageService, new SimpleMeterRegistry(), editingContextMetadataProvider); UploadFile file = new UploadFile(FILE_NAME, inputstream); var input = new UploadDocumentInput(UUID.randomUUID(), UUID.randomUUID().toString(), file, false); @@ -243,7 +248,10 @@ public Optional createDocument(String projectId, String name, String c } }; IServicesMessageService messageService = new NoOpServicesMessageService(); - UploadDocumentEventHandler handler = new UploadDocumentEventHandler(documentService, messageService, new SimpleMeterRegistry()); + var editingContextMetadata = new EditingContextMetadata(List.of()); + IEditingContextMetadataProvider editingContextMetadataProvider = editingContextId -> editingContextMetadata; + + UploadDocumentEventHandler handler = new UploadDocumentEventHandler(documentService, messageService, new SimpleMeterRegistry(), editingContextMetadataProvider); UploadFile file = new UploadFile(FILE_NAME, new ByteArrayInputStream(resourceBytes)); var input = new UploadDocumentInput(UUID.randomUUID(), UUID.randomUUID().toString(), file, false); diff --git a/packages/view/backend/sirius-components-view/src/main/java/org/eclipse/sirius/components/view/util/services/ColorPaletteService.java b/packages/view/backend/sirius-components-view/src/main/java/org/eclipse/sirius/components/view/util/services/ColorPaletteService.java index b5a3719a33..ee98c257f9 100644 --- a/packages/view/backend/sirius-components-view/src/main/java/org/eclipse/sirius/components/view/util/services/ColorPaletteService.java +++ b/packages/view/backend/sirius-components-view/src/main/java/org/eclipse/sirius/components/view/util/services/ColorPaletteService.java @@ -41,7 +41,7 @@ public UserColor getColorFromPalette(Object object, String colorName) { UserColor color = this.getColorFromPalette(this.colorPalettesView, colorName); if (color == null && object instanceof EObject eObject) { - color = this.getColorFromPalette(this.getView(object), colorName); + color = this.getColorFromPalette(this.getView(eObject), colorName); } return color; }