From 628278f6804fea8d96137b0ad37b8c08d14ae731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20ROU=C3=8BN=C3=89?= Date: Tue, 4 Jul 2023 13:40:52 +0200 Subject: [PATCH] [2125] Add the possibility to programmatically order and filter pages of a form. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: https://github.com/eclipse-sirius/sirius-components/issues/2125 Signed-off-by: Florian ROUËNÉ --- CHANGELOG.adoc | 17 +++-- .../forms/FormEventProcessor.java | 37 ++++++----- .../forms/FormEventProcessorFactory.java | 30 ++++----- .../PropertiesEventProcessorFactory.java | 32 ++++----- .../RelatedElementsEventProcessorFactory.java | 28 ++++---- .../RepresentationsEventProcessorFactory.java | 29 +++++---- .../forms/api/IFormPostProcessor.java | 39 +++++++++++ .../FormEventProcessorConfiguration.java | 32 +++++++++ ...ormEventProcessorFactoryConfiguration.java | 65 +++++++++++++++++++ .../forms/FormEventProcessorTests.java | 22 ++++--- 10 files changed, 238 insertions(+), 93 deletions(-) create mode 100644 packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/api/IFormPostProcessor.java create mode 100644 packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/configuration/FormEventProcessorConfiguration.java create mode 100644 packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/configuration/FormEventProcessorFactoryConfiguration.java diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 9cf10edda8..8a8be517e2 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -30,8 +30,7 @@ This allows for code which does not depend on Sirius Web and the Document notion === Bug fixes -- https://github.com/eclipse-sirius/sirius-components/issues/2058[#2058] [view] Fix an issue where the default icon for List widget candidates was missing when the candidates wer -e not EObjects. +- https://github.com/eclipse-sirius/sirius-components/issues/2058[#2058] [view] Fix an issue where the default icon for List widget candidates was missing when the candidates were not EObjects. - https://github.com/eclipse-sirius/sirius-components/issues/2060[#2060] [form] Fix an issue where the list widget was displayed on a single line inside a flexbox container, no matter the length of the labels of its items. - https://github.com/eclipse-sirius/sirius-components/issues/2076[#2076] [sirius-web] Fix `EditingDomainFactoryService` declaration to use an interface. - https://github.com/eclipse-sirius/sirius-components/issues/2032[#2032] [form] Add domainType on PageDescription in the view DSL and takes into account the impacts for the FormDescriptionAggregator. @@ -59,7 +58,10 @@ image:doc/screenshots/ShowIconOptionSelectWidget.jpg[Icons on select widget opti - https://github.com/eclipse-sirius/sirius-components/issues/2077[#2077] [form] Add the ability to define a border style for groups and flexbox containers. - https://github.com/eclipse-sirius/sirius-components/issues/2080[#2080] [tree] Add an initial label value when editing tree items label. - https://github.com/eclipse-sirius/sirius-components/issues/2080[#2080] [tree] Add an inital label value when editing tree items label. -- https://github.com/eclipse-sirius/sirius-components/issues/2090[#2090] [diagram] Add the support for the arrange all on react flow diagram. The arrange all is made with elkjs. +- https://github.com/eclipse-sirius/sirius-components/issues/2090[#2090] [diagram] Add the support for the arrange all on react flow diagram. +The arrange all is made with elkjs. +- https://github.com/eclipse-sirius/sirius-components/issues/2125[#2125] [form] Add the API `IFormPostProcessor` to programmatically modify all forms just before they are published on the subscription. +Note that IFormPostProcessor is a singleton, if several rules must be applied to several forms, a mechanism has to be added to the implementation. === Improvements @@ -80,7 +82,8 @@ The help text can include multiple lines (separated by `\n`), but no text format + image:doc/images/Widget_Help_Tooltip.png[Example of a help tooltip on a widget] + -- https://github.com/eclipse-sirius/sirius-components/issues/2048[#2048] [diagram] Add a basic support for the resize. It is possible to reduce the size of a node less than the space needed to display all children. +- https://github.com/eclipse-sirius/sirius-components/issues/2048[#2048] [diagram] Add a basic support for the resize. +It is possible to reduce the size of a node less than the space needed to display all children. - https://github.com/eclipse-sirius/sirius-components/issues/2064[#2064] [forms] Make the `IWidgetDescriptor` API more flexible. - https://github.com/eclipse-sirius/sirius-components/issues/1618[#1618] [view] Split the view metamodel into dedicated subpackages. - https://github.com/eclipse-sirius/sirius-components/issues/2083[#2083] [diagram] Add support for edge markers @@ -184,14 +187,15 @@ image:doc/screenshots/filterBarFilterButton.png[Filter Bar Filter Button,30%,30% - https://github.com/eclipse-sirius/sirius-components/issues/1914[#1914] [form] It is now possible for applications to provide their own custom widgets without forking Sirius Components. See link:doc/how-to/contribute-custom-widget.adoc[the documentation] for more details. -- https://github.com/eclipse-sirius/sirius-components/issues/1830[#1830] [layout] This feature is experimental and can be activated on a diagram by adding "__EXPERIMENTAL" to its name. The new algorithm does the minimum possible to place node without overlap. +- https://github.com/eclipse-sirius/sirius-components/issues/1830[#1830] [layout] This feature is experimental and can be activated on a diagram by adding "__EXPERIMENTAL" to its name. +The new algorithm does the minimum possible to place node without overlap. - https://github.com/eclipse-sirius/sirius-components/issues/1985[|#1985] [sirius-web] It is now possible to use in-memory View-based representations by registering them in the new `InMemoryViewRegistry`. These representations can be created programmatically or loaded from `.view` EMF models on startup, and do not need to be stored as documents inside a project in the database. - https://github.com/eclipse-sirius/sirius-components/issues/1921[#1921] [view] Added a project sirius-components-view-builder. + Introducing providers interfaces to help creating view programmatically. + -Introducing a generator of builders aimed to help creating view programmatically, the generation makes use of emf-merge and modifications to these builders can be annotated to live during future regeneration. +Introducing a generator of builders aimed to help creating view programmatically, the generation makes use of emf-merge and modifications to these builders can be annotated to live during future regeneration. - https://github.com/eclipse-sirius/sirius-components/issues/1912[#1912] [core] Add the possibility to send feedback messages to the frontend after an action. - https://github.com/eclipse-sirius/sirius-components/issues/1989[#1989] [diagram] Contribute a new way to render diagrams to evaluate an alternate layouting strategy @@ -249,7 +253,6 @@ Such calls will not work anymore since `null` will not be an acceptable value an + Removing dependencies from sirius-components-compatibility-emf in the canHandle methods of sirius-components-view-emf services - === Dependency update - [form] Switch to lexical 0.8.1 diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessor.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessor.java index 61f7b9b0a0..7b4fa6f2cf 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessor.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessor.java @@ -27,7 +27,9 @@ import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; import org.eclipse.sirius.components.collaborative.forms.api.IFormInput; +import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor; import org.eclipse.sirius.components.collaborative.forms.api.IWidgetSubscriptionManager; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration; import org.eclipse.sirius.components.collaborative.forms.dto.FormRefreshedEventPayload; import org.eclipse.sirius.components.collaborative.forms.dto.RenameFormInput; import org.eclipse.sirius.components.collaborative.forms.dto.UpdateWidgetFocusInput; @@ -84,17 +86,21 @@ public class FormEventProcessor implements IFormEventProcessor { private final AtomicReference
currentForm = new AtomicReference<>(); - public FormEventProcessor(IEditingContext editingContext, FormCreationParameters formCreationParameters, List widgetDescriptors, List formEventHandlers, - ISubscriptionManager subscriptionManager, IWidgetSubscriptionManager widgetSubscriptionManager, IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { - this.logger.trace("Creating the form event processor {}", formCreationParameters.getId()); + private final IFormPostProcessor formPostProcessor; - this.editingContext = Objects.requireNonNull(editingContext); - this.formCreationParameters = Objects.requireNonNull(formCreationParameters); - this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); - this.formEventHandlers = Objects.requireNonNull(formEventHandlers); + public FormEventProcessor(FormEventProcessorConfiguration configuration, + ISubscriptionManager subscriptionManager, IWidgetSubscriptionManager widgetSubscriptionManager, + IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry, IFormPostProcessor formPostProcessor) { + this.logger.trace("Creating the form event processor {}", configuration.formCreationParameters().getId()); + + this.editingContext = Objects.requireNonNull(configuration.editingContext()); + this.formCreationParameters = Objects.requireNonNull(configuration.formCreationParameters()); + this.widgetDescriptors = Objects.requireNonNull(configuration.widgetDescriptors()); + this.formEventHandlers = Objects.requireNonNull(configuration.formEventHandlers()); this.subscriptionManager = Objects.requireNonNull(subscriptionManager); this.widgetSubscriptionManager = Objects.requireNonNull(widgetSubscriptionManager); this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry); + this.formPostProcessor = Objects.requireNonNull(formPostProcessor); Form form = this.refreshForm(); this.currentForm.set(form); @@ -114,16 +120,13 @@ public ISubscriptionManager getSubscriptionManager() { @Override public void handle(One payloadSink, Many changeDescriptionSink, IRepresentationInput representationInput) { IRepresentationInput effectiveInput = representationInput; - if (representationInput instanceof RenameRepresentationInput) { - RenameRepresentationInput renameRepresentationInput = (RenameRepresentationInput) representationInput; + if (representationInput instanceof RenameRepresentationInput renameRepresentationInput) { effectiveInput = new RenameFormInput(renameRepresentationInput.id(), renameRepresentationInput.editingContextId(), renameRepresentationInput.representationId(), renameRepresentationInput.newLabel()); } - if (effectiveInput instanceof IFormInput) { - IFormInput formInput = (IFormInput) effectiveInput; + if (effectiveInput instanceof IFormInput formInput) { - if (formInput instanceof UpdateWidgetFocusInput) { - UpdateWidgetFocusInput input = (UpdateWidgetFocusInput) formInput; + if (formInput instanceof UpdateWidgetFocusInput input) { this.widgetSubscriptionManager.handle(input); payloadSink.tryEmitValue(new UpdateWidgetFocusSuccessPayload(input.id(), input.widgetId())); @@ -159,11 +162,9 @@ public void refresh(ChangeDescription changeDescription) { } private boolean shouldRefresh(ChangeDescription changeDescription) { - // @formatter:off return this.representationRefreshPolicyRegistry.getRepresentationRefreshPolicy(this.formCreationParameters.getFormDescription()) .orElseGet(this::getDefaultRefreshPolicy) .shouldRefresh(changeDescription); - // @formatter:on } @@ -182,6 +183,8 @@ private Form refreshForm() { Element element = new Element(FormComponent.class, formComponentProps); Form form = new FormRenderer(this.widgetDescriptors).render(element); + form = this.formPostProcessor.postProcess(form, variableManager); + this.logger.trace("Form refreshed: {}", form.getId()); return form; @@ -192,13 +195,11 @@ public Flux getOutputEvents(IInput input) { var initialRefresh = Mono.fromCallable(() -> new FormRefreshedEventPayload(input.id(), this.currentForm.get())); var refreshEventFlux = Flux.concat(initialRefresh, this.sink.asFlux()); - // @formatter:off return Flux.merge( refreshEventFlux, this.widgetSubscriptionManager.getFlux(input), this.subscriptionManager.getFlux(input) - ); - // @formatter:on + ); } @Override diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorFactory.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorFactory.java index 93a1607389..3d9ca443e8 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorFactory.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorFactory.java @@ -27,7 +27,10 @@ import org.eclipse.sirius.components.collaborative.forms.api.FormCreationParameters; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; +import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor; import org.eclipse.sirius.components.collaborative.forms.api.IWidgetSubscriptionManagerFactory; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorFactoryConfiguration; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService; @@ -61,16 +64,18 @@ public class FormEventProcessorFactory implements IRepresentationEventProcessorF private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; - public FormEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IObjectService objectService, List widgetDescriptors, - List formEventHandlers, IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory) { + private final IFormPostProcessor formPostProcessor; + + public FormEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, List widgetDescriptors, FormEventProcessorFactoryConfiguration formConfiguration) { this.representationDescriptionSearchService = Objects.requireNonNull(configuration.getRepresentationDescriptionSearchService()); this.representationSearchService = Objects.requireNonNull(configuration.getRepresentationSearchService()); this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); - this.objectService = Objects.requireNonNull(objectService); + this.objectService = Objects.requireNonNull(formConfiguration.getObjectService()); this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); - this.formEventHandlers = Objects.requireNonNull(formEventHandlers); - this.widgetSubscriptionManagerFactory = Objects.requireNonNull(widgetSubscriptionManagerFactory); + this.formEventHandlers = Objects.requireNonNull(formConfiguration.getFormEventHandlers()); + this.widgetSubscriptionManagerFactory = Objects.requireNonNull(formConfiguration.getWidgetSubscriptionManagerFactory()); this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); + this.formPostProcessor = Objects.requireNonNull(formConfiguration.getFormPostProcessor()); } @Override @@ -81,39 +86,34 @@ public boolean canHandle(Class repr @Override public Optional createRepresentationEventProcessor(Class representationEventProcessorClass, IRepresentationConfiguration configuration, IEditingContext editingContext) { - if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof FormConfiguration) { - FormConfiguration formConfiguration = (FormConfiguration) configuration; + if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof FormConfiguration formConfiguration) { Optional optionalForm = this.representationSearchService.findById(editingContext, formConfiguration.getId(), Form.class); if (optionalForm.isPresent()) { Form form = optionalForm.get(); - // @formatter:off Optional optionalFormDescription = this.representationDescriptionSearchService.findById(editingContext, form.getDescriptionId()) .filter(FormDescription.class::isInstance) .map(FormDescription.class::cast); - // @formatter:on Optional optionalObject = this.objectService.getObject(editingContext, form.getTargetObjectId()); if (optionalFormDescription.isPresent() && optionalObject.isPresent()) { FormDescription formDescription = optionalFormDescription.get(); Object object = optionalObject.get(); - // @formatter:off FormCreationParameters formCreationParameters = FormCreationParameters.newFormCreationParameters(formConfiguration.getId()) .editingContext(editingContext) .formDescription(formDescription) .object(object) .selection(List.of()) .build(); - // @formatter:on - IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.widgetDescriptors, this.formEventHandlers, - this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); + IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(new FormEventProcessorConfiguration(editingContext, formCreationParameters, this.widgetDescriptors, + this.formEventHandlers), + this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry, + this.formPostProcessor); - // @formatter:off return Optional.of(formEventProcessor) .filter(representationEventProcessorClass::isInstance) .map(representationEventProcessorClass::cast); - // @formatter:on } } diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/PropertiesEventProcessorFactory.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/PropertiesEventProcessorFactory.java index 5f2db820b2..84e3f2ac2a 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/PropertiesEventProcessorFactory.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/PropertiesEventProcessorFactory.java @@ -26,10 +26,13 @@ import org.eclipse.sirius.components.collaborative.forms.api.FormCreationParameters; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; +import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor; import org.eclipse.sirius.components.collaborative.forms.api.IPropertiesDefaultDescriptionProvider; import org.eclipse.sirius.components.collaborative.forms.api.IPropertiesDescriptionService; import org.eclipse.sirius.components.collaborative.forms.api.IWidgetSubscriptionManagerFactory; import org.eclipse.sirius.components.collaborative.forms.api.PropertiesConfiguration; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorFactoryConfiguration; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.forms.description.FormDescription; @@ -44,6 +47,7 @@ */ @Service public class PropertiesEventProcessorFactory implements IRepresentationEventProcessorFactory { + public static final String DETAILS_VIEW_ID = UUID.nameUUIDFromBytes("details-view".getBytes()).toString(); private final IPropertiesDescriptionService propertiesDescriptionService; @@ -62,17 +66,19 @@ public class PropertiesEventProcessorFactory implements IRepresentationEventProc private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; - public PropertiesEventProcessorFactory(IPropertiesDescriptionService propertiesDescriptionService, IPropertiesDefaultDescriptionProvider propertiesDefaultDescriptionProvider, - IObjectService objectService, List widgetDescriptors, List formEventHandlers, RepresentationEventProcessorFactoryConfiguration configuration, - IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory) { + private final IFormPostProcessor formPostProcessor; + + public PropertiesEventProcessorFactory(IPropertiesDescriptionService propertiesDescriptionService, IPropertiesDefaultDescriptionProvider propertiesDefaultDescriptionProvider, List widgetDescriptors, + RepresentationEventProcessorFactoryConfiguration configuration, FormEventProcessorFactoryConfiguration formConfiguration) { this.propertiesDescriptionService = Objects.requireNonNull(propertiesDescriptionService); this.propertiesDefaultDescriptionProvider = Objects.requireNonNull(propertiesDefaultDescriptionProvider); - this.objectService = Objects.requireNonNull(objectService); + this.objectService = Objects.requireNonNull(formConfiguration.getObjectService()); this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); - this.formEventHandlers = Objects.requireNonNull(formEventHandlers); + this.formEventHandlers = Objects.requireNonNull(formConfiguration.getFormEventHandlers()); this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); - this.widgetSubscriptionManagerFactory = Objects.requireNonNull(widgetSubscriptionManagerFactory); + this.widgetSubscriptionManagerFactory = Objects.requireNonNull(formConfiguration.getWidgetSubscriptionManagerFactory()); this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); + this.formPostProcessor = Objects.requireNonNull(formConfiguration.getFormPostProcessor()); } @Override @@ -83,16 +89,13 @@ public boolean canHandle(Class repr @Override public Optional createRepresentationEventProcessor(Class representationEventProcessorClass, IRepresentationConfiguration configuration, IEditingContext editingContext) { - if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof PropertiesConfiguration) { - PropertiesConfiguration propertiesConfiguration = (PropertiesConfiguration) configuration; + if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof PropertiesConfiguration propertiesConfiguration) { List pageDescriptions = this.propertiesDescriptionService.getPropertiesDescriptions(); - // @formatter:off var objects = propertiesConfiguration.getObjectIds().stream() .map(objectId -> this.objectService.getObject(editingContext, objectId)) .flatMap(Optional::stream) .toList(); - // @formatter:on if (!objects.isEmpty()) { Optional optionalFormDescription = Optional.empty(); if (!pageDescriptions.isEmpty()) { @@ -100,23 +103,20 @@ public Optional createRepresentatio } FormDescription formDescription = optionalFormDescription.orElse(this.propertiesDefaultDescriptionProvider.getFormDescription()); - // @formatter:off FormCreationParameters formCreationParameters = FormCreationParameters.newFormCreationParameters(propertiesConfiguration.getId()) .editingContext(editingContext) .formDescription(formDescription) .object(objects.get(0)) .selection(objects) .build(); - // @formatter:on - IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.widgetDescriptors, this.formEventHandlers, - this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); + IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(new FormEventProcessorConfiguration(editingContext, formCreationParameters, + this.widgetDescriptors, this.formEventHandlers), + this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry, this.formPostProcessor); - // @formatter:off return Optional.of(formEventProcessor) .filter(representationEventProcessorClass::isInstance) .map(representationEventProcessorClass::cast); - // @formatter:on } } return Optional.empty(); diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RelatedElementsEventProcessorFactory.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RelatedElementsEventProcessorFactory.java index 9eeed1cfc6..57be4ae046 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RelatedElementsEventProcessorFactory.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RelatedElementsEventProcessorFactory.java @@ -25,9 +25,12 @@ import org.eclipse.sirius.components.collaborative.forms.api.FormCreationParameters; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; +import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor; import org.eclipse.sirius.components.collaborative.forms.api.IRelatedElementsDescriptionProvider; import org.eclipse.sirius.components.collaborative.forms.api.IWidgetSubscriptionManagerFactory; import org.eclipse.sirius.components.collaborative.forms.api.RelatedElementsConfiguration; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorFactoryConfiguration; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.forms.description.FormDescription; @@ -56,15 +59,18 @@ public class RelatedElementsEventProcessorFactory implements IRepresentationEven private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; + private final IFormPostProcessor formPostProcessor; + public RelatedElementsEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IRelatedElementsDescriptionProvider relatedElementsDescriptionProvider, - IObjectService objectService, List widgetDescriptors, List formEventHandlers, IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory) { + List widgetDescriptors, FormEventProcessorFactoryConfiguration formConfiguration) { this.relatedElementsDescriptionProvider = Objects.requireNonNull(relatedElementsDescriptionProvider); - this.objectService = Objects.requireNonNull(objectService); + this.objectService = Objects.requireNonNull(formConfiguration.getObjectService()); this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); - this.formEventHandlers = Objects.requireNonNull(formEventHandlers); + this.formEventHandlers = Objects.requireNonNull(formConfiguration.getFormEventHandlers()); this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); - this.widgetSubscriptionManagerFactory = Objects.requireNonNull(widgetSubscriptionManagerFactory); + this.widgetSubscriptionManagerFactory = Objects.requireNonNull(formConfiguration.getWidgetSubscriptionManagerFactory()); this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); + this.formPostProcessor = Objects.requireNonNull(formConfiguration.getFormPostProcessor()); } @Override @@ -75,34 +81,28 @@ public boolean canHandle(Class repr @Override public Optional createRepresentationEventProcessor(Class representationEventProcessorClass, IRepresentationConfiguration configuration, IEditingContext editingContext) { - if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof RelatedElementsConfiguration) { - RelatedElementsConfiguration relatedElementsConfiguration = (RelatedElementsConfiguration) configuration; + if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof RelatedElementsConfiguration relatedElementsConfiguration) { - // @formatter:off var objects = relatedElementsConfiguration.getObjectIds().stream() .map(objectId -> this.objectService.getObject(editingContext, objectId)) .flatMap(Optional::stream) .toList(); - // @formatter:on if (!objects.isEmpty()) { FormDescription formDescription = this.relatedElementsDescriptionProvider.getFormDescription(); - // @formatter:off FormCreationParameters formCreationParameters = FormCreationParameters.newFormCreationParameters(relatedElementsConfiguration.getId()) .editingContext(editingContext) .formDescription(formDescription) .object(objects.get(0)) .selection(objects) .build(); - // @formatter:on - IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.widgetDescriptors, this.formEventHandlers, - this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); + IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(new FormEventProcessorConfiguration(editingContext, formCreationParameters, + this.widgetDescriptors, this.formEventHandlers), + this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry, this.formPostProcessor); - // @formatter:off return Optional.of(formEventProcessor) .filter(representationEventProcessorClass::isInstance) .map(representationEventProcessorClass::cast); - // @formatter:on } } return Optional.empty(); diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RepresentationsEventProcessorFactory.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RepresentationsEventProcessorFactory.java index f041c615c0..7d9a9264aa 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RepresentationsEventProcessorFactory.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RepresentationsEventProcessorFactory.java @@ -24,9 +24,12 @@ import org.eclipse.sirius.components.collaborative.forms.api.FormCreationParameters; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; +import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor; import org.eclipse.sirius.components.collaborative.forms.api.IRepresentationsDescriptionProvider; import org.eclipse.sirius.components.collaborative.forms.api.IWidgetSubscriptionManagerFactory; import org.eclipse.sirius.components.collaborative.forms.api.RepresentationsConfiguration; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorFactoryConfiguration; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.forms.description.FormDescription; @@ -52,15 +55,17 @@ public class RepresentationsEventProcessorFactory implements IRepresentationEven private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; - public RepresentationsEventProcessorFactory(IRepresentationsDescriptionProvider representationsDescriptionProvider, IObjectService objectService, List formEventHandlers, - ISubscriptionManagerFactory subscriptionManagerFactory, IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory, - IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { + private final IFormPostProcessor formPostProcessor; + + public RepresentationsEventProcessorFactory(IRepresentationsDescriptionProvider representationsDescriptionProvider, ISubscriptionManagerFactory subscriptionManagerFactory, + IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry, FormEventProcessorFactoryConfiguration formConfiguration) { this.representationsDescriptionProvider = Objects.requireNonNull(representationsDescriptionProvider); - this.objectService = Objects.requireNonNull(objectService); - this.formEventHandlers = Objects.requireNonNull(formEventHandlers); + this.objectService = Objects.requireNonNull(formConfiguration.getObjectService()); + this.formEventHandlers = Objects.requireNonNull(formConfiguration.getFormEventHandlers()); this.subscriptionManagerFactory = Objects.requireNonNull(subscriptionManagerFactory); - this.widgetSubscriptionManagerFactory = Objects.requireNonNull(widgetSubscriptionManagerFactory); + this.widgetSubscriptionManagerFactory = Objects.requireNonNull(formConfiguration.getWidgetSubscriptionManagerFactory()); this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry); + this.formPostProcessor = Objects.requireNonNull(formConfiguration.getFormPostProcessor()); } @Override @@ -71,30 +76,26 @@ public boolean canHandle(Class repr @Override public Optional createRepresentationEventProcessor(Class representationEventProcessorClass, IRepresentationConfiguration configuration, IEditingContext editingContext) { - if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof RepresentationsConfiguration) { - RepresentationsConfiguration representationsConfiguration = (RepresentationsConfiguration) configuration; + if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof RepresentationsConfiguration representationsConfiguration) { FormDescription formDescription = this.representationsDescriptionProvider.getRepresentationsDescription(); Optional optionalObject = this.objectService.getObject(editingContext, representationsConfiguration.getObjectId()); if (optionalObject.isPresent()) { Object object = optionalObject.get(); - // @formatter:off FormCreationParameters formCreationParameters = FormCreationParameters.newFormCreationParameters(representationsConfiguration.getId()) .editingContext(editingContext) .formDescription(formDescription) .object(object) .selection(List.of()) .build(); - // @formatter:on - FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), this.formEventHandlers, this.subscriptionManagerFactory.create(), - this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); + FormEventProcessor formEventProcessor = new FormEventProcessor(new FormEventProcessorConfiguration(editingContext, formCreationParameters, List.of(), + this.formEventHandlers), this.subscriptionManagerFactory.create(), + this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry, this.formPostProcessor); - // @formatter:off return Optional.of(formEventProcessor) .filter(representationEventProcessorClass::isInstance) .map(representationEventProcessorClass::cast); - // @formatter:on } } diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/api/IFormPostProcessor.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/api/IFormPostProcessor.java new file mode 100644 index 0000000000..bc181482bd --- /dev/null +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/api/IFormPostProcessor.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2023 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.components.collaborative.forms.api; + +import org.eclipse.sirius.components.forms.Form; +import org.eclipse.sirius.components.representations.VariableManager; + +/** + * Interface to give the possibility to make changes on a form. + * + * @author frouene + */ +public interface IFormPostProcessor { + + Form postProcess(Form form, VariableManager variableManager); + + /** + * Implementation which does nothing, used for default behavior. + * + * @author frouene + */ + class NoOp implements IFormPostProcessor { + + @Override + public Form postProcess(Form form, VariableManager variableManager) { + return form; + } + } +} diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/configuration/FormEventProcessorConfiguration.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/configuration/FormEventProcessorConfiguration.java new file mode 100644 index 0000000000..bed691e8ad --- /dev/null +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/configuration/FormEventProcessorConfiguration.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2023 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.components.collaborative.forms.configuration; + +import java.util.List; + +import org.eclipse.sirius.components.collaborative.forms.api.FormCreationParameters; +import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; +import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; + +/** + * Bundles the common dependencies that {@link IFormEventProcessor} implementations need + * into a single object for convenience. + * + * @author frouene + */ +public record FormEventProcessorConfiguration(IEditingContext editingContext, FormCreationParameters formCreationParameters, List widgetDescriptors, + List formEventHandlers) { + +} diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/configuration/FormEventProcessorFactoryConfiguration.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/configuration/FormEventProcessorFactoryConfiguration.java new file mode 100644 index 0000000000..6a7d6f9add --- /dev/null +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/configuration/FormEventProcessorFactoryConfiguration.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2023 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.components.collaborative.forms.configuration; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessorFactory; +import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; +import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor; +import org.eclipse.sirius.components.collaborative.forms.api.IWidgetSubscriptionManagerFactory; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.springframework.context.annotation.Configuration; + +/** + * Bundles the common dependencies that most {@link IRepresentationEventProcessorFactory} implementations for Form Representation need + * into a single object for convenience. + * + * @author frouene + */ +@Configuration +public class FormEventProcessorFactoryConfiguration { + + private final IObjectService objectService; + + private final List formEventHandlers; + + private final IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory; + + private final Optional optionalFormProcessor; + + public FormEventProcessorFactoryConfiguration(IObjectService objectService, List formEventHandlers, IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory, Optional optionalFormProcessor) { + this.objectService = Objects.requireNonNull(objectService); + this.formEventHandlers = Objects.requireNonNull(formEventHandlers); + this.widgetSubscriptionManagerFactory = Objects.requireNonNull(widgetSubscriptionManagerFactory); + this.optionalFormProcessor = Objects.requireNonNull(optionalFormProcessor); + } + + public IObjectService getObjectService() { + return this.objectService; + } + + public List getFormEventHandlers() { + return this.formEventHandlers; + } + + public IWidgetSubscriptionManagerFactory getWidgetSubscriptionManagerFactory() { + return this.widgetSubscriptionManagerFactory; + } + + public IFormPostProcessor getFormPostProcessor() { + return this.optionalFormProcessor.orElse(new IFormPostProcessor.NoOp()); + } +} diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/test/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorTests.java b/packages/forms/backend/sirius-components-collaborative-forms/src/test/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorTests.java index a0a4d96e07..b4cc729daf 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/test/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorTests.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/test/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorTests.java @@ -19,6 +19,8 @@ import org.eclipse.sirius.components.collaborative.api.ChangeDescription; import org.eclipse.sirius.components.collaborative.api.ChangeKind; import org.eclipse.sirius.components.collaborative.forms.api.FormCreationParameters; +import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration; import org.eclipse.sirius.components.collaborative.forms.dto.FormEventInput; import org.eclipse.sirius.components.collaborative.forms.dto.FormRefreshedEventPayload; import org.eclipse.sirius.components.collaborative.representations.RepresentationRefreshPolicyRegistry; @@ -55,8 +57,7 @@ private FormDescription getFormDescription() { private Predicate getRefreshFormEventPayloadPredicate() { return representationEventPayload -> { - if (representationEventPayload instanceof FormRefreshedEventPayload) { - FormRefreshedEventPayload payload = (FormRefreshedEventPayload) representationEventPayload; + if (representationEventPayload instanceof FormRefreshedEventPayload payload) { return payload.form() != null; } return false; @@ -77,8 +78,9 @@ public void testEmitFormOnSubscription() { .build(); // @formatter:on - FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), List.of(), new SubscriptionManager(), new WidgetSubscriptionManager(), - new RepresentationRefreshPolicyRegistry()); + FormEventProcessor formEventProcessor = new FormEventProcessor(new FormEventProcessorConfiguration(editingContext, formCreationParameters, List.of(), List.of()), + new SubscriptionManager(), new WidgetSubscriptionManager(), + new RepresentationRefreshPolicyRegistry(), new IFormPostProcessor.NoOp()); // @formatter:off StepVerifier.create(formEventProcessor.getOutputEvents(input)) @@ -102,8 +104,9 @@ public void testEmitFormOnRefresh() { .build(); // @formatter:on - FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), List.of(), new SubscriptionManager(), new WidgetSubscriptionManager(), - new RepresentationRefreshPolicyRegistry()); + FormEventProcessor formEventProcessor = new FormEventProcessor(new FormEventProcessorConfiguration(editingContext, formCreationParameters, List.of(), List.of()), + new SubscriptionManager(), new WidgetSubscriptionManager(), + new RepresentationRefreshPolicyRegistry(), new IFormPostProcessor.NoOp()); Runnable performRefresh = () -> formEventProcessor.refresh(new ChangeDescription(ChangeKind.SEMANTIC_CHANGE, input.formId(), input)); @@ -131,10 +134,11 @@ public void testCompleteOnDispose() { .build(); // @formatter:on - FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), List.of(), new SubscriptionManager(), new WidgetSubscriptionManager(), - new RepresentationRefreshPolicyRegistry()); + FormEventProcessor formEventProcessor = new FormEventProcessor(new FormEventProcessorConfiguration(editingContext, formCreationParameters, List.of(), List.of()), + new SubscriptionManager(), new WidgetSubscriptionManager(), + new RepresentationRefreshPolicyRegistry(), new IFormPostProcessor.NoOp()); - Runnable disposeFormEventProcessor = () -> formEventProcessor.dispose(); + Runnable disposeFormEventProcessor = formEventProcessor::dispose; // @formatter:off StepVerifier.create(formEventProcessor.getOutputEvents(input))