diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UpdateDescriptionTemplatePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UpdateDescriptionTemplatePersist.java index 2598c726a..3c2031e39 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UpdateDescriptionTemplatePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UpdateDescriptionTemplatePersist.java @@ -28,16 +28,16 @@ public class UpdateDescriptionTemplatePersist { this.id = id; } - private UUID descriptionTemplateGroupId; + private String hash; - public static final String _descriptionTemplateGroupId = "descriptionTemplateGroupId"; + public static final String _hash = "hash"; - public UUID getDescriptionTemplateGroupId() { - return descriptionTemplateGroupId; + public String getHash() { + return hash; } - public void setDescriptionTemplateGroupId(UUID descriptionTemplateGroupId) { - this.descriptionTemplateGroupId = descriptionTemplateGroupId; + public void setHash(String hash) { + this.hash = hash; } @Component(UpdateDescriptionTemplatePersistValidator.ValidatorName) @@ -61,6 +61,10 @@ public class UpdateDescriptionTemplatePersist { @Override protected List specifications(UpdateDescriptionTemplatePersist item) { return Arrays.asList( + this.spec() + .iff(() -> this.isValidGuid(item.getId())) + .must(() -> this.isValidHash(item.getHash())) + .failOn(UpdateDescriptionTemplatePersist._hash).failWith(messageSource.getMessage("Validation_Required", new Object[]{UpdateDescriptionTemplatePersist._hash}, LocaleContextHolder.getLocale())), this.spec() .must(() -> this.isValidGuid(item.getId())) .failOn(UpdateDescriptionTemplatePersist._id) diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java index 43071c959..67a848213 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java @@ -10,6 +10,7 @@ import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.exception.MyValidationException; import gr.cite.tools.fieldset.FieldSet; +import jakarta.xml.bind.JAXBException; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.multipart.MultipartFile; @@ -37,5 +38,5 @@ public interface DescriptionService { StorageFile uploadFieldFile(DescriptionFieldFilePersist model, MultipartFile file, FieldSet fields) throws IOException; StorageFileEntity getFieldFile(UUID descriptionId, UUID storageFileId); - void updateDescriptionTemplate(UpdateDescriptionTemplatePersist model) throws InvalidApplicationException, IOException; + void updateDescriptionTemplate(UpdateDescriptionTemplatePersist model) throws InvalidApplicationException, IOException, JAXBException; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java index d35f4c5f7..a8ba4aea7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java @@ -52,6 +52,7 @@ import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; import gr.cite.tools.validation.ValidatorFactory; +import jakarta.xml.bind.JAXBException; import org.apache.commons.io.FilenameUtils; import org.jetbrains.annotations.NotNull; import org.slf4j.LoggerFactory; @@ -236,7 +237,7 @@ public class DescriptionServiceImpl implements DescriptionService { return this.builderFactory.builder(DescriptionBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, Description._id), data); } @Override - public void updateDescriptionTemplate(UpdateDescriptionTemplatePersist model) throws InvalidApplicationException, IOException { + public void updateDescriptionTemplate(UpdateDescriptionTemplatePersist model) throws InvalidApplicationException, IOException, JAXBException { logger.debug(new MapLogEntry("update description template").And("model", model)); this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.descriptionAffiliation(model.getId())), Permission.EditDescription); @@ -269,6 +270,7 @@ public class DescriptionServiceImpl implements DescriptionService { eu.eudat.commons.types.descriptiontemplate.DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(eu.eudat.commons.types.descriptiontemplate.DefinitionEntity.class, latestVersionDescriptionTemplates.getFirst().getDefinition()); PropertyDefinitionEntity propertyDefinition = this.xmlHandlingService.fromXmlSafe(PropertyDefinitionEntity.class, data.getProperties()); + data.setProperties(this.xmlHandlingService.toXml(this.cleanPropertyDefinitionEntity(propertyDefinition, definition))); data.setUpdatedAt(Instant.now()); this.entityManager.merge(data); @@ -304,6 +306,50 @@ public class DescriptionServiceImpl implements DescriptionService { } } + private @NotNull PropertyDefinitionEntity cleanPropertyDefinitionEntity(PropertyDefinitionEntity data, eu.eudat.commons.types.descriptiontemplate.DefinitionEntity definition) { + PropertyDefinitionEntity cleanData = new PropertyDefinitionEntity(); + if (data == null) return cleanData; + if (data.getFieldSets() != null && !data.getFieldSets().isEmpty()){ + cleanData.setFieldSets(new HashMap<>()); + for (String key: data.getFieldSets().keySet()) { + FieldSetEntity fieldSetEntity = definition != null ? definition.getFieldSetById(key).stream().findFirst().orElse(null) : null; + if (fieldSetEntity != null){ + cleanData.getFieldSets().put(key, this.cleanPropertyDefinitionFieldSetEntity(data.getFieldSets().get(key), fieldSetEntity)); + } + } + } + return cleanData; + } + + private @NotNull PropertyDefinitionFieldSetEntity cleanPropertyDefinitionFieldSetEntity(PropertyDefinitionFieldSetEntity persist, FieldSetEntity fieldSetEntity) { + PropertyDefinitionFieldSetEntity cleanData = new PropertyDefinitionFieldSetEntity(); + if (persist == null) return cleanData; + if (!this.conventionService.isListNullOrEmpty(persist.getItems())){ + cleanData.setItems(new ArrayList<>()); + for (PropertyDefinitionFieldSetItemEntity itemsPersist: persist.getItems()) { + cleanData.getItems().add(this.cleanPropertyDefinitionFieldSetItemEntity(itemsPersist, fieldSetEntity)); + } + } + return cleanData; + } + + private @NotNull PropertyDefinitionFieldSetItemEntity cleanPropertyDefinitionFieldSetItemEntity(PropertyDefinitionFieldSetItemEntity data, FieldSetEntity fieldSetEntity) { + PropertyDefinitionFieldSetItemEntity cleanData = new PropertyDefinitionFieldSetItemEntity(); + if (data == null) return cleanData; + if (data.getFields() != null && !data.getFields().isEmpty()){ + cleanData.setOrdinal(data.getOrdinal()); + cleanData.setComment(data.getComment()); + cleanData.setFields(new HashMap<>()); + for (String key: data.getFields().keySet()) { + eu.eudat.commons.types.descriptiontemplate.FieldEntity fieldEntity = fieldSetEntity != null ? fieldSetEntity.getFieldById(key).stream().findFirst().orElse(null) : null; + if (fieldEntity != null){ + cleanData.getFields().put(key,data.getFields().get(key)); + } + } + } + return cleanData; + } + private void createDescriptionNotificationEvent(DescriptionEntity description, UserEntity user, NotificationContactType type) throws InvalidApplicationException { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); event.setUserId(this.userScope.getUserId()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java index 7b15b0ea9..028b0d501 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java @@ -35,6 +35,7 @@ import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; +import jakarta.xml.bind.JAXBException; import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; @@ -272,7 +273,7 @@ public class DescriptionController { @PostMapping("update-description-template") @Transactional @ValidationFilterAnnotation(validator = UpdateDescriptionTemplatePersist.UpdateDescriptionTemplatePersistValidator.ValidatorName, argumentName = "model") - public Boolean updateDescriptionTemplate(@RequestBody UpdateDescriptionTemplatePersist model) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, IOException { + public Boolean updateDescriptionTemplate(@RequestBody UpdateDescriptionTemplatePersist model) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, IOException, JAXBException { logger.debug(new MapLogEntry("update description template" + Description.class.getSimpleName()).And("model", model)); this.descriptionService.updateDescriptionTemplate(model); diff --git a/dmp-frontend/src/app/core/model/description/description.ts b/dmp-frontend/src/app/core/model/description/description.ts index 781672c47..56e5dd49e 100644 --- a/dmp-frontend/src/app/core/model/description/description.ts +++ b/dmp-frontend/src/app/core/model/description/description.ts @@ -152,5 +152,5 @@ export interface DescriptionSectionPermissionResolver { export interface UpdateDescriptionTemplatePersist { id: Guid; - descriptionTemplateGroupId: Guid; + hash?: string; } diff --git a/dmp-frontend/src/app/ui/description/editor/description-base-fields-editor/description-base-fields-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-base-fields-editor/description-base-fields-editor.component.ts index f927f271e..f165eff8c 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-base-fields-editor/description-base-fields-editor.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-base-fields-editor/description-base-fields-editor.component.ts @@ -24,12 +24,12 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent { @Input() description: Description; availableDescriptionTemplates: DescriptionTemplate[] = []; viewOnly = false; //TODO: not used. - + @Output() refresh: EventEmitter = new EventEmitter(); constructor(private dialog: MatDialog, - private descriptionService: DescriptionService) { - super(); + private descriptionService: DescriptionService) { + super(); } ngOnInit() { @@ -39,7 +39,7 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent { public compareWith(object1: any, object2: any) { return object1 && object2 && object1.id === object2.id; } - + private loadDescriptionTemplates(): void { const dmpDescriptionTemplates: DmpDescriptionTemplate[] = this.description.dmp.dmpDescriptionTemplates.filter(x => x.sectionId == this.description.dmpDescriptionTemplate.sectionId && x.isActive == IsActive.Active); const currentVersionsOfDescriptionTemplates = dmpDescriptionTemplates.map(x => x.currentDescriptionTemplate); @@ -53,7 +53,7 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent { } this.availableDescriptionTemplates.push(...currentVersionsOfDescriptionTemplates); } - + private openDeprecatedDescriptionTemplateDialog(): void { const dialogRef = this.dialog.open(DeprecatedDescriptionTemplateDialog, { data: { @@ -65,7 +65,7 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent { if(result) { this.descriptionService.updateDescriptionTemplate({ id: this.description.id, - descriptionTemplateGroupId: this.description.descriptionTemplate.groupId + hash: this.description.hash }) .subscribe( result => {