Skip to content

Commit

Permalink
[4203] Add a documentation field in Representation metadata
Browse files Browse the repository at this point in the history
Bug: eclipse-sirius#4203
Signed-off-by: Jerome Gout <[email protected]>
  • Loading branch information
jerome-obeo authored and sbegaudeau committed Dec 6, 2024
1 parent 26b8205 commit 56841ee
Show file tree
Hide file tree
Showing 14 changed files with 325 additions and 37 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@

=== Deprecation warning

- [form] The project `sirius-components-collecborative-forms` has always decided that any change performed by a widget must be a `ChangeKind.SEMANTIC_CHANGE`.
This decision has created some limit on what can really be edited by a form.
We will soon change this default behavior to use the change kind and parameters returned by the specifier in the `Success` result from the event handler.
As a result, if we consider a textfield widget, in order to keep the existing behavior, specifier will have to create a result with the proper change kind like `new Success(ChangeKind.SEMANTIC_CHANGE, Map.of())` instead of `new Success()`.
If the status returned by the event handler is still something like `new Success()` then, Sirius Components will ignore the change performed by the event handler.
While it can be useful to indicate that nothing has changed in some cases, if it's not done on purpose some representations will not be updated, semantic data may not be saved, etc.
This change will also be propagated over time to other kind of representations.


=== Breaking changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public final class ChangeKind {

public static final String RELOAD_REPRESENTATION = "RELOAD_REPRESENTATION";

public static final String REPRESENTATION_METADATA_UPDATE = "REPRESENTATION_METADATA_UPDATE";

private ChangeKind() {
// Prevent instantiation
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public void handle(One<IPayload> payloadSink, Many<ChangeDescription> changeDesc
}
if (status instanceof Success success) {
payload = new SuccessPayload(formInput.id(), success.getMessages());
if (success.getChangeKind() == null || success.getChangeKind().isBlank()) {
if (success.getChangeKind().isBlank()) {
changeDescription = new ChangeDescription(ChangeKind.SEMANTIC_CHANGE, formInput.representationId(), formInput);
} else {
changeDescription = new ChangeDescription(success.getChangeKind(), formInput.representationId(), formInput, success.getParameters());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* Copyright (c) 2024 CEA LIST.
* 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
Expand All @@ -13,7 +13,6 @@

package org.eclipse.sirius.web.application.representation.services;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -34,6 +33,7 @@
import org.eclipse.sirius.components.forms.description.AbstractControlDescription;
import org.eclipse.sirius.components.forms.description.GroupDescription;
import org.eclipse.sirius.components.forms.description.PageDescription;
import org.eclipse.sirius.components.forms.description.TextareaDescription;
import org.eclipse.sirius.components.forms.description.TextfieldDescription;
import org.eclipse.sirius.components.representations.Failure;
import org.eclipse.sirius.components.representations.IStatus;
Expand Down Expand Up @@ -82,31 +82,18 @@ private PageDescription getPageDescription() {
}

private List<AbstractControlDescription> createControlDescriptions() {
List<AbstractControlDescription> controls = new ArrayList<>();

BiFunction<Object, String, IStatus> representationLabelWriter = (metadata, newLabel) -> {
// delegate the renaming of the representation to EditingContextEventProcessor
var representationId = ((RepresentationMetadata) metadata).getId();
Map<String, Object> parameters = new HashMap<>();
parameters.put(EditingContextEventProcessor.REPRESENTATION_ID, representationId.toString());
parameters.put(EditingContextEventProcessor.REPRESENTATION_LABEL, newLabel);
return new Success(ChangeKind.REPRESENTATION_TO_RENAME, parameters);
};
var labelControl = this.createLabelTextField();
var documentationControl = this.createDocumentationTextArea();

var label = this.createTextField("metadata.label", "Label",
metadata -> ((RepresentationMetadata) metadata).getLabel(),
representationLabelWriter);
controls.add(label);
return controls;
return List.of(labelControl, documentationControl);
}


private GroupDescription createGroupDescription(List<AbstractControlDescription> controls) {
Function<VariableManager, List<?>> semanticElementsProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class).stream().toList();

return GroupDescription.newGroupDescription("group")
.idProvider(variableManager -> "group")
.labelProvider(variableManager -> "Core properties")
.labelProvider(variableManager -> "Core Properties")
.semanticElementsProvider(semanticElementsProvider)
.controlDescriptions(controls)
.build();
Expand All @@ -127,28 +114,67 @@ private PageDescription createPageDescription(String id, GroupDescription groupD
.build();
}

private TextfieldDescription createTextField(String id, String title, Function<Object, String> reader, BiFunction<Object, String, IStatus> writer) {
Function<VariableManager, String> valueProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class)
.map(reader)
private TextfieldDescription createLabelTextField() {
Function<VariableManager, String> valueProvider = variableManager -> variableManager.get(VariableManager.SELF, RepresentationMetadata.class)
.map(RepresentationMetadata::getLabel)
.orElse("");

BiFunction<VariableManager, String, IStatus> newValueHandler = (variableManager, newValue) -> {
var self = variableManager.get(VariableManager.SELF, RepresentationMetadata.class);
if (self.isPresent()) {
var representationMetadata = self.get();

// delegate the renaming of the representation to EditingContextEventProcessor
Map<String, Object> parameters = new HashMap<>();
parameters.put(EditingContextEventProcessor.REPRESENTATION_ID, representationMetadata.getId().toString());
parameters.put(EditingContextEventProcessor.REPRESENTATION_LABEL, newValue);
return new Success(ChangeKind.REPRESENTATION_TO_RENAME, parameters);
}
return new Failure("");
};

Function<VariableManager, String> semanticTargetIdProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class)
.map(this.identityService::getId)
.orElse(null);

return TextfieldDescription.newTextfieldDescription("metadata.label")
.idProvider(variableManager -> "metadata.label")
.targetObjectIdProvider(semanticTargetIdProvider)
.labelProvider(variableManager -> "Label")
.valueProvider(valueProvider)
.newValueHandler(newValueHandler)
.diagnosticsProvider(variableManager -> List.of())
.kindProvider(this::kindProvider)
.messageProvider(this::messageProvider)
.isReadOnlyProvider(variableManager -> false)
.build();
}

private TextareaDescription createDocumentationTextArea() {
Function<VariableManager, String> valueProvider = variableManager -> variableManager.get(VariableManager.SELF, RepresentationMetadata.class)
.map(RepresentationMetadata::getDocumentation)
.orElse("");

BiFunction<VariableManager, String, IStatus> newValueHandler = (variableManager, newValue) -> {
var self = variableManager.get(VariableManager.SELF, Object.class);
var self = variableManager.get(VariableManager.SELF, RepresentationMetadata.class);
if (self.isPresent()) {
return writer.apply(self.get(), newValue);
} else {
return new Failure("");
var representationMetadata = self.get();
return Optional.of(this.representationMetadataUpdateService.updateDocumentation(null, representationMetadata.getId(), newValue))
.filter(org.eclipse.sirius.web.domain.services.Success.class::isInstance)
.map(success -> (IStatus) new Success(ChangeKind.REPRESENTATION_METADATA_UPDATE, Map.of()))
.orElseGet(() -> new Failure(""));
}
return new Failure("");
};

Function<VariableManager, String> semanticTargetIdProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class)
.map(this.identityService::getId)
.orElse(null);

return org.eclipse.sirius.components.forms.description.TextfieldDescription.newTextfieldDescription(id)
.idProvider(variableManager -> id)
return TextareaDescription.newTextareaDescription("metadata.documentation")
.idProvider(variableManager -> "metadata.documentation")
.targetObjectIdProvider(semanticTargetIdProvider)
.labelProvider(variableManager -> title)
.labelProvider(variableManager -> "Documentation")
.valueProvider(valueProvider)
.newValueHandler(newValueHandler)
.diagnosticsProvider(variableManager -> List.of())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* Copyright (c) 2024 CEA LIST.
* 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
Expand All @@ -17,13 +17,12 @@
import org.eclipse.sirius.components.collaborative.api.ChangeKind;
import org.eclipse.sirius.components.collaborative.api.IRepresentationRefreshPolicy;
import org.eclipse.sirius.components.collaborative.api.IRepresentationRefreshPolicyProvider;
import org.eclipse.sirius.components.collaborative.portals.PortalChangeKind;
import org.eclipse.sirius.components.representations.IRepresentationDescription;
import org.eclipse.sirius.web.application.views.details.services.PropertiesEventProcessorFactory;
import org.springframework.stereotype.Service;

/**
* The representation refresh policy provider for the representation representations.
* The representation refresh policy provider for the representation metadata properties page.
*
* @author Jerome Gout
*/
Expand All @@ -36,9 +35,7 @@ public class RepresentationMetadataDetailsViewRefreshPolicyProvider implements I
ChangeKind.REPRESENTATION_RENAMING,
ChangeKind.REPRESENTATION_TO_DELETE,
ChangeKind.REPRESENTATION_METADATA_UPDATE,
ChangeKind.SEMANTIC_CHANGE,
PortalChangeKind.PORTAL_VIEW_ADDITION.name(),
PortalChangeKind.PORTAL_VIEW_REMOVAL.name());
ChangeKind.SEMANTIC_CHANGE);


@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public void save(ICause cause, IEditingContext editingContext, org.eclipse.siriu
.iconURLs(representationMetadata.iconURLs().stream()
.map(RepresentationIconURL::new)
.toList())
.documentation("")
.build(cause);

this.representationMetadataCreationService.create(boundedRepresentationMetadata);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public class RepresentationMetadata extends AbstractValidatingAggregateRoot<Repr
@MappedCollection(idColumn = "representation_metadata_id", keyColumn = "index")
private List<RepresentationIconURL> iconURLs = new ArrayList<>();

private String documentation;

@Override
public UUID getId() {
return this.id;
Expand Down Expand Up @@ -113,6 +115,21 @@ public List<RepresentationIconURL> getIconURLs() {
return Collections.unmodifiableList(this.iconURLs);
}

public String getDocumentation() {
return this.documentation;
}

public void updateDocumentation(ICause cause, String newDocumentation) {
if (this.documentation.isEmpty() || !this.documentation.equals(newDocumentation)) {
this.documentation = newDocumentation;

var now = Instant.now();
this.lastModifiedOn = now;

this.registerEvent(new RepresentationMetadataUpdatedEvent(UUID.randomUUID(), now, cause, this));
}
}

public void dispose(ICause cause) {
this.registerEvent(new RepresentationMetadataDeletedEvent(UUID.randomUUID(), Instant.now(), cause, this));
}
Expand Down Expand Up @@ -148,6 +165,8 @@ public static final class Builder {

private List<RepresentationIconURL> iconURLs;

private String documentation;

public Builder(UUID id) {
this.id = Objects.requireNonNull(id);
}
Expand Down Expand Up @@ -182,6 +201,11 @@ public Builder iconURLs(List<RepresentationIconURL> iconURLs) {
return this;
}

public Builder documentation(String documentation) {
this.documentation = Objects.requireNonNull(documentation);
return this;
}

public RepresentationMetadata build(ICause cause) {
var representationMetadata = new RepresentationMetadata();
representationMetadata.isNew = true;
Expand All @@ -192,6 +216,7 @@ public RepresentationMetadata build(ICause cause) {
representationMetadata.label = Objects.requireNonNull(this.label);
representationMetadata.kind = Objects.requireNonNull(this.kind);
representationMetadata.iconURLs = Objects.requireNonNull(this.iconURLs);
representationMetadata.documentation = Objects.requireNonNull(this.documentation);

var now = Instant.now();
representationMetadata.createdOn = now;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.UUID;

import org.eclipse.sirius.components.events.ICause;
import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.RepresentationMetadata;
import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.repositories.IRepresentationMetadataRepository;
import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.services.api.IRepresentationMetadataUpdateService;
import org.eclipse.sirius.web.domain.services.Failure;
Expand Down Expand Up @@ -56,4 +57,20 @@ public IResult<Void> updateLabel(ICause cause, UUID representationMetadataId, St

return result;
}

@Override
public IResult<RepresentationMetadata> updateDocumentation(ICause cause, UUID representationMetadataId, String documentation) {
IResult<RepresentationMetadata> result = new Failure<>(this.messageService.notFound());

var optionalRepresentationMetadata = this.representationMetadataRepository.findMetadataById(representationMetadataId);
if (optionalRepresentationMetadata.isPresent()) {
var representationMetadata = optionalRepresentationMetadata.get();
representationMetadata.updateDocumentation(cause, documentation);
this.representationMetadataRepository.save(representationMetadata);

result = new Success<>(representationMetadata);
}

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.UUID;

import org.eclipse.sirius.components.events.ICause;
import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.RepresentationMetadata;
import org.eclipse.sirius.web.domain.services.IResult;

/**
Expand All @@ -25,4 +26,6 @@
public interface IRepresentationMetadataUpdateService {

IResult<Void> updateLabel(ICause cause, UUID representationMetadataId, String label);

IResult<RepresentationMetadata> updateDocumentation(ICause cause, UUID representationMetadataId, String documentation);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2024 CEA LIST.
~ 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
-->
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">

<changeSet id="02-add-representation-metadata-documentation" author="Jerome Gout">
<addColumn tableName="representation_metadata">
<column name="documentation" type="TEXT"/>
</addColumn>

<sql>
UPDATE representation_metadata
SET documentation = ''
</sql>

<addNotNullConstraint tableName="representation_metadata" columnName="documentation" />
</changeSet>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">
<include file="db/changelog/2025.1/01-add-representation-metadata-icon-url.xml" />
<include file="db/changelog/2025.1/02-add-representation-metadata-documentation.xml" />
</databaseChangeLog>
Loading

0 comments on commit 56841ee

Please sign in to comment.