From 6c49b7e7c22b8088f2f5e39e7ee3878e24b1cab1 Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Wed, 15 Nov 2023 17:06:49 +0200 Subject: [PATCH] description persist --- .../data/DescriptionReferenceEntity.java | 2 - .../model/persist/DescriptionPersist.java | 95 +++++--- .../persist/DescriptionReferencePersist.java | 54 +++++ .../eudat/model/persist/ReferencePersist.java | 3 - .../descriptionproperties/FieldPersist.java | 34 +++ .../PropertyDefinitionPersist.java | 21 ++ .../main/java/eu/eudat/query/TagQuery.java | 23 ++ .../description/DescriptionService.java | 3 +- .../description/DescriptionServiceImpl.java | 210 ++++++++++++++++-- .../DescriptionTemplateServiceImpl.java | 2 +- .../java/eu/eudat/controllers/Datasets.java | 20 +- .../controllers/v2/DescriptionController.java | 5 +- 12 files changed, 411 insertions(+), 61 deletions(-) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionReferencePersist.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptionproperties/FieldPersist.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptionproperties/PropertyDefinitionPersist.java diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/DescriptionReferenceEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/DescriptionReferenceEntity.java index b4f4cecef..f630f2543 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/DescriptionReferenceEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/DescriptionReferenceEntity.java @@ -34,13 +34,11 @@ public class DescriptionReferenceEntity { public static final String _referenceId = "referenceId"; @Column(name = "created_at") - @Convert(converter = DateToUTCConverter.class) private Instant createdAt; public static final String _createdAt = "createdAt"; @Column(name = "updated_at") - @Convert(converter = DateToUTCConverter.class) private Instant updatedAt; public static final String _updatedAt = "updatedAt"; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionPersist.java index 39f9ea214..8addd1ab7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionPersist.java @@ -1,29 +1,56 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.DescriptionStatus; -import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.validation.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.ValidEnum; import eu.eudat.commons.validation.ValidId; +import eu.eudat.data.DescriptionEntity; +import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionPersist; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.util.List; import java.util.UUID; +@FieldNotNullIfOtherSet(message = "{validation.hashempty}") public class DescriptionPersist { @ValidId(message = "{validation.invalidid}") private UUID id; + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + @Size(max = DescriptionEntity._labelLength, message = "{validation.largerthanmax}") private String label; - private UUID dmp; + @NotNull(message = "{validation.empty}") + @ValidId(message = "{validation.invalidid}") + private UUID dmpId; - private String properties; - - private UUID profile; + @NotNull(message = "{validation.empty}") + @ValidId(message = "{validation.invalidid}") + private UUID dmpDescriptionTemplateId; + @ValidEnum(message = "{validation.empty}") private DescriptionStatus status; private String description; - private IsActive isActive; + @NotNull(message = "{validation.empty}") + @Valid + private PropertyDefinitionPersist properties; + + @NotNull(message = "{validation.empty}") + @Valid + private List tags; + + @NotNull(message = "{validation.empty}") + @Valid + private List references; + + private String hash; public UUID getId() { return id; @@ -41,28 +68,20 @@ public class DescriptionPersist { this.label = label; } - public UUID getDmp() { - return dmp; + public UUID getDmpId() { + return dmpId; } - public void setDmp(UUID dmp) { - this.dmp = dmp; + public void setDmpId(UUID dmpId) { + this.dmpId = dmpId; } - public String getProperties() { - return properties; + public UUID getDmpDescriptionTemplateId() { + return dmpDescriptionTemplateId; } - public void setProperties(String properties) { - this.properties = properties; - } - - public UUID getProfile() { - return profile; - } - - public void setProfile(UUID profile) { - this.profile = profile; + public void setDmpDescriptionTemplateId(UUID dmpDescriptionTemplateId) { + this.dmpDescriptionTemplateId = dmpDescriptionTemplateId; } public DescriptionStatus getStatus() { @@ -81,11 +100,35 @@ public class DescriptionPersist { this.description = description; } - public IsActive getIsActive() { - return isActive; + public PropertyDefinitionPersist getProperties() { + return properties; } - public void setIsActive(IsActive isActive) { - this.isActive = isActive; + public void setProperties(PropertyDefinitionPersist properties) { + this.properties = properties; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public List getReferences() { + return references; + } + + public void setReferences(List references) { + this.references = references; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionReferencePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionReferencePersist.java new file mode 100644 index 000000000..070b39000 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionReferencePersist.java @@ -0,0 +1,54 @@ +package eu.eudat.model.persist; + + +import eu.eudat.commons.enums.DescriptionTemplateStatus; +import eu.eudat.commons.validation.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.ValidId; +import eu.eudat.data.DescriptionTemplateEntity; +import eu.eudat.model.persist.descriptiontemplatedefinition.DefinitionPersist; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +import java.util.List; +import java.util.UUID; + +@FieldNotNullIfOtherSet(message = "{validation.hashempty}") +public class DescriptionReferencePersist { + @ValidId(message = "{validation.invalidid}") + private UUID id; + + @NotNull(message = "{validation.empty}") + @Valid + private ReferencePersist reference = null; + + private String hash; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public ReferencePersist getReference() { + return reference; + } + + public void setReference(ReferencePersist reference) { + this.reference = reference; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } +} + + diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferencePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferencePersist.java index ea0073ad8..1c2efdb6b 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferencePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferencePersist.java @@ -48,9 +48,6 @@ public class ReferencePersist { private String hash; - //private UserInfoPersist createdBy; ToDo - - public UUID getId() { return id; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptionproperties/FieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptionproperties/FieldPersist.java new file mode 100644 index 000000000..d7dd2bf6b --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptionproperties/FieldPersist.java @@ -0,0 +1,34 @@ +package eu.eudat.model.persist.descriptionproperties; + + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; + +public class FieldPersist { + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + private String key; + + + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + private String value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} + + diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptionproperties/PropertyDefinitionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptionproperties/PropertyDefinitionPersist.java new file mode 100644 index 000000000..bbf9d6c60 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptionproperties/PropertyDefinitionPersist.java @@ -0,0 +1,21 @@ +package eu.eudat.model.persist.descriptionproperties; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +public class PropertyDefinitionPersist { + + @NotNull(message = "{validation.empty}") + @Valid + private List fields; + + public List getFields() { + return fields; + } + + public void setFields(List fields) { + this.fields = fields; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/TagQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/TagQuery.java index 9ad575aed..d83a363bd 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/TagQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/TagQuery.java @@ -24,6 +24,7 @@ import java.util.*; public class TagQuery extends QueryBase { private String like; + private Collection labels; private Collection ids; @@ -58,6 +59,21 @@ public class TagQuery extends QueryBase { return this; } + public TagQuery labels(String value) { + this.labels = List.of(value); + return this; + } + + public TagQuery labels(String... value) { + this.labels = Arrays.asList(value); + return this; + } + + public TagQuery labels(Collection values) { + this.labels = values; + return this; + } + public TagQuery excludedIds(Collection values) { this.excludedIds = values; return this; @@ -113,6 +129,7 @@ public class TagQuery extends QueryBase { return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || + this.isEmpty(this.labels) || this.isEmpty(this.excludedIds) || this.isEmpty(this.createdByIds); } @@ -134,6 +151,12 @@ public class TagQuery extends QueryBase { inClause.value(item); predicates.add(inClause); } + if (this.labels != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(TagEntity._label)); + for (String item : this.labels) + inClause.value(item); + predicates.add(inClause); + } if (this.excludedIds != null) { CriteriaBuilder.In notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(TagEntity._id)); for (UUID item : this.excludedIds) 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 0abdde04f..79ea829e2 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 @@ -1,5 +1,6 @@ package eu.eudat.service.description; +import com.fasterxml.jackson.core.JsonProcessingException; import eu.eudat.model.Description; import eu.eudat.model.persist.DescriptionPersist; import gr.cite.tools.exception.MyApplicationException; @@ -14,7 +15,7 @@ import java.util.UUID; public interface DescriptionService { - Description persist(DescriptionPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException; + Description persist(DescriptionPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException; void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException, IOException; 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 64b476132..1192d2e0e 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 @@ -1,25 +1,34 @@ package eu.eudat.service.description; +import com.fasterxml.jackson.core.JsonProcessingException; import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.authorization.Permission; import eu.eudat.commons.JsonHandlingService; +import eu.eudat.commons.XmlHandlingService; import eu.eudat.commons.enums.DescriptionStatus; import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.scope.user.UserScope; +import eu.eudat.commons.types.description.FieldEntity; +import eu.eudat.commons.types.description.PropertyDefinitionEntity; +import eu.eudat.commons.types.reference.DefinitionEntity; import eu.eudat.convention.ConventionService; -import eu.eudat.data.DescriptionEntity; -import eu.eudat.data.DescriptionReferenceEntity; -import eu.eudat.data.DescriptionTagEntity; +import eu.eudat.data.*; import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.event.DescriptionTouchedEvent; import eu.eudat.event.EventBroker; import eu.eudat.model.Description; +import eu.eudat.model.DescriptionReference; import eu.eudat.model.builder.DescriptionBuilder; import eu.eudat.model.deleter.DescriptionDeleter; +import eu.eudat.model.deleter.DescriptionReferenceDeleter; +import eu.eudat.model.deleter.DescriptionTagDeleter; import eu.eudat.model.persist.DescriptionPersist; -import eu.eudat.query.DescriptionQuery; -import eu.eudat.query.DescriptionReferenceQuery; -import eu.eudat.query.DescriptionTagQuery; +import eu.eudat.model.persist.DescriptionReferencePersist; +import eu.eudat.model.persist.ReferencePersist; +import eu.eudat.model.persist.descriptionproperties.FieldPersist; +import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionPersist; +import eu.eudat.model.persist.referencedefinition.DefinitionPersist; +import eu.eudat.query.*; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.deleter.DeleterFactory; @@ -33,6 +42,7 @@ import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; import jakarta.persistence.EntityManager; +import org.jetbrains.annotations.NotNull; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; @@ -42,8 +52,10 @@ import org.springframework.stereotype.Service; import javax.management.InvalidApplicationException; import java.io.IOException; import java.time.Instant; +import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; @Service public class DescriptionServiceImpl implements DescriptionService { @@ -71,6 +83,7 @@ public class DescriptionServiceImpl implements DescriptionService { private final JsonHandlingService jsonHandlingService; private final UserScope userScope; + private final XmlHandlingService xmlHandlingService; @Autowired public DescriptionServiceImpl( @@ -83,7 +96,9 @@ public class DescriptionServiceImpl implements DescriptionService { MessageSource messageSource, EventBroker eventBroker, QueryFactory queryFactory, - JsonHandlingService jsonHandlingService, UserScope userScope) { + JsonHandlingService jsonHandlingService, + UserScope userScope, + XmlHandlingService xmlHandlingService) { this.entityManager = entityManager; this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; @@ -95,10 +110,13 @@ public class DescriptionServiceImpl implements DescriptionService { this.queryFactory = queryFactory; this.jsonHandlingService = jsonHandlingService; this.userScope = userScope; + this.xmlHandlingService = xmlHandlingService; } + //region Persist + @Override - public Description persist(DescriptionPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException { + public Description persist(DescriptionPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException { logger.debug(new MapLogEntry("persisting data dmp").And("model", model).And("fields", fields)); this.authorizationService.authorizeForce(Permission.EditDescription); @@ -108,8 +126,9 @@ public class DescriptionServiceImpl implements DescriptionService { DescriptionEntity data; if (isUpdate) { data = this.entityManager.find(DescriptionEntity.class, model.getId()); - if (data == null) - throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Description.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Description.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); + if (data.getStatus() == DescriptionStatus.Finalized) throw new MyForbiddenException("Can not update finalized template"); } else { data = new DescriptionEntity(); data.setId(UUID.randomUUID()); @@ -118,21 +137,176 @@ public class DescriptionServiceImpl implements DescriptionService { } data.setLabel(model.getLabel()); - data.setProperties(model.getProperties()); + data.setProperties(this.jsonHandlingService.toJson(this.buildPropertyDefinitionEntity(model.getProperties()))); data.setStatus(model.getStatus()); data.setDescription(model.getDescription()); data.setUpdatedAt(Instant.now()); - if (isUpdate) - this.entityManager.merge(data); - else - this.entityManager.persist(data); + if (isUpdate) this.entityManager.merge(data); + else this.entityManager.persist(data); + this.persistTags(data.getId(), model.getTags()); + this.entityManager.flush(); this.eventBroker.emit(new DescriptionTouchedEvent(data.getId())); return this.builderFactory.builder(DescriptionBuilder.class).authorize(AuthorizationFlags.OwnerOrPermissionOrMemberOrPublic).build(BaseFieldSet.build(fields, Description._id), data); } + private @NotNull PropertyDefinitionEntity buildPropertyDefinitionEntity(PropertyDefinitionPersist persist){ + PropertyDefinitionEntity data = new PropertyDefinitionEntity(); + if (persist == null) return data; + if (!this.conventionService.isListNullOrEmpty(persist.getFields())){ + data.setFields(new ArrayList<>()); + for (FieldPersist sectionPersist: persist.getFields()) { + data.getFields().add(this.buildFieldEntity(sectionPersist)); + } + } + return data; + } + + private @NotNull FieldEntity buildFieldEntity(FieldPersist persist){ + FieldEntity data = new FieldEntity(); + if (persist == null) return data; + + data.setKey(persist.getKey()); + data.setValue(persist.getValue()); + return data; + } + + + private void persistTags(UUID id, List tagLabels) throws InvalidApplicationException { + if (tagLabels == null) tagLabels = new ArrayList<>(); + tagLabels = tagLabels.stream().filter(x-> x != null && !x.isBlank()).toList(); + + List items = this.queryFactory.query(DescriptionTagQuery.class).isActive(IsActive.Active).descriptionIds(id).collect(); + List tagsAlreadyLinked = this.queryFactory.query(TagQuery.class).isActive(IsActive.Active).ids(items.stream().map(DescriptionTagEntity::getTagId).collect(Collectors.toList())).collect(); + List tagLabelsToAdd = tagLabels.stream().filter(x-> tagsAlreadyLinked.stream().noneMatch(y-> y.getLabel() != null && y.getLabel().equalsIgnoreCase(x))).toList(); + List existingTags = this.queryFactory.query(TagQuery.class).isActive(IsActive.Active).labels(tagLabelsToAdd).createdByIds(this.userScope.getUserId()).collect(); + + List updatedCreatedIds = new ArrayList<>(); + for (String tagLabel : tagLabels) { + TagEntity alreadyLinkedTag = tagsAlreadyLinked.stream().filter(x-> x.getLabel() != null && x.getLabel().equalsIgnoreCase(tagLabel)).findFirst().orElse(null); + if (alreadyLinkedTag != null){ + updatedCreatedIds.addAll(items.stream().filter(x-> x.getTagId().equals(alreadyLinkedTag.getId())).map(DescriptionTagEntity::getId).toList()); + } else{ + TagEntity existingTag = existingTags.stream().filter(x-> x.getLabel() != null && x.getLabel().equalsIgnoreCase(tagLabel)).findFirst().orElse(null); + if (existingTag == null){ + existingTag = new TagEntity(); + existingTag.setId(UUID.randomUUID()); + existingTag.setLabel(tagLabel); + existingTag.setIsActive(IsActive.Active); + existingTag.setCreatedAt(Instant.now()); + existingTag.setUpdatedAt(Instant.now()); + this.entityManager.persist(existingTag); + } + + DescriptionTagEntity link = new DescriptionTagEntity(); + link.setId(UUID.randomUUID()); + link.setTagId(existingTag.getId()); + link.setDescriptionId(id); + link.setIsActive(IsActive.Active); + link.setCreatedAt(Instant.now()); + link.setUpdatedAt(Instant.now()); + this.entityManager.persist(link); + updatedCreatedIds.add(link.getId()); + } + } + List toDelete = items.stream().filter(x-> updatedCreatedIds.stream().noneMatch(y-> y.equals(x.getId()))).collect(Collectors.toList()); + + this.deleterFactory.deleter(DescriptionTagDeleter.class).delete(toDelete); + } + + private void persistDescriptionReferences(UUID id, List models) throws InvalidApplicationException { + if (models == null) models = new ArrayList<>(); + + List items = this.queryFactory.query(DescriptionReferenceQuery.class).isActive(IsActive.Active).descriptionIds(id).collect(); + List existingReferences = this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).ids(models.stream().filter(x-> this.conventionService.isValidGuid(x.getReference().getId())).map(x-> x.getReference().getId()).distinct().toList()).collect(); + + List updatedCreatedIds = new ArrayList<>(); + for (DescriptionReferencePersist model : models) { + Boolean isUpdate = this.conventionService.isValidGuid(model.getId()); + DescriptionReferenceEntity data; + if (isUpdate) { + data = items.stream().filter(x -> x.getId().equals(model.getId())).findFirst().orElse(null); + if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DescriptionReference.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); + if (!data.getReferenceId().equals(model.getReference().getId())) throw new MyForbiddenException("Can not change reference of DescriptionReferenceEntity"); + } else { + data = new DescriptionReferenceEntity(); + data.setId(UUID.randomUUID()); + data.setIsActive(IsActive.Active); + data.setCreatedAt(Instant.now()); + } + ReferenceEntity referenceEntity = this.persisReference(existingReferences, model.getReference()); + data.setReferenceId(referenceEntity.getId()); + data.setUpdatedAt(Instant.now()); + + if (isUpdate) this.entityManager.merge(data); + else this.entityManager.persist(data); + + updatedCreatedIds.add(data.getId()); + } + List toDelete = items.stream().filter(x-> updatedCreatedIds.stream().noneMatch(y-> y.equals(x.getId()))).collect(Collectors.toList()); + + this.deleterFactory.deleter(DescriptionReferenceDeleter.class).delete(toDelete); + } + + private ReferenceEntity persisReference(List existingReferences, ReferencePersist model) throws InvalidApplicationException { + Boolean isUpdate = this.conventionService.isValidGuid(model.getId()); + ReferenceEntity data; + if (isUpdate) { + data = existingReferences.stream().filter(x -> x.getId().equals(model.getId())).findFirst().orElse(null); + if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DescriptionReference.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); + } else { + data = new ReferenceEntity(); + data.setId(UUID.randomUUID()); + data.setIsActive(IsActive.Active); + data.setCreatedAt(Instant.now()); + } + + data.setDefinition(this.xmlHandlingService.toXmlSafe(this.buildDefinitionEntity(model.getDefinition()))); + data.setUpdatedAt(Instant.now()); + data.setReference(model.getReference()); + data.setAbbreviation(model.getAbbreviation()); + data.setSource(model.getSource()); + data.setSourceType(model.getSourceType()); + data.setUpdatedAt(Instant.now()); + + if (isUpdate) this.entityManager.merge(data); + else this.entityManager.persist(data); + + return data; + } + + private @NotNull DefinitionEntity buildDefinitionEntity(DefinitionPersist persist){ + DefinitionEntity data = new DefinitionEntity(); + if (persist == null) return data; + if (!this.conventionService.isListNullOrEmpty(persist.getFields())){ + data.setFields(new ArrayList<>()); + for (eu.eudat.model.persist.referencedefinition.FieldPersist fieldPersist: persist.getFields()) { + data.getFields().add(this.buildFieldEntity(fieldPersist)); + } + } + + return data; + } + + private @NotNull eu.eudat.commons.types.reference.FieldEntity buildFieldEntity(eu.eudat.model.persist.referencedefinition.FieldPersist persist){ + eu.eudat.commons.types.reference.FieldEntity data = new eu.eudat.commons.types.reference.FieldEntity(); + if (persist == null) return data; + + data.setCode(persist.getCode()); + data.setDataType(persist.getDataType()); + data.setCode(persist.getCode()); + + return data; + } + + //endregion + + //region delete + @Override public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException, IOException { logger.debug("deleting description: {}", id); @@ -141,7 +315,11 @@ public class DescriptionServiceImpl implements DescriptionService { this.deleterFactory.deleter(DescriptionDeleter.class).deleteAndSaveByIds(List.of(id), false); } + + //endregion + //region clone + @Override public void clone(UUID dmpId, UUID descriptionId) throws InvalidApplicationException { logger.debug("cloning description: {} with dmp: {}", descriptionId, dmpId); @@ -202,5 +380,7 @@ public class DescriptionServiceImpl implements DescriptionService { this.entityManager.flush(); } + + //endregion } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java index 5177b5384..b27c0005c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java @@ -183,7 +183,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic List items = this.queryFactory.query(UserDescriptionTemplateQuery.class).isActive(IsActive.Active).descriptionTemplateIds(id).collect(); List updatedCreatedIds = new ArrayList<>(); for (UserDescriptionTemplatePersist user : users) { - UserDescriptionTemplateEntity data = items.stream().filter(x -> x.getUser() == user.getUserId() && x.getRole() == user.getRole()).findFirst().orElse(null); + UserDescriptionTemplateEntity data = items.stream().filter(x -> x.getUser().equals(user.getUserId()) && x.getRole().equals(user.getRole())).findFirst().orElse(null); if (data == null){ data = new UserDescriptionTemplateEntity(); data.setId(UUID.randomUUID()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index 5bfcd976b..3ddf38a57 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -267,16 +267,16 @@ public class Datasets extends BaseController { * Data Management * */ - @Transactional - @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") - public @ResponseBody - ResponseEntity> createOrUpdate(@RequestBody DatasetWizardModel profile) throws Exception { - this.authorizationService.authorizeForce(Permission.AuthenticatedRole); - - DatasetWizardModel dataset = new DatasetWizardModel().fromDataModel(this.datasetManager.createOrUpdate(profile)); -// dataset.setTags(profile.getTags()); //TODO - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(dataset)); - } +// @Transactional +// @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") +// public @ResponseBody +// ResponseEntity> createOrUpdate(@RequestBody DatasetWizardModel profile) throws Exception { +// this.authorizationService.authorizeForce(Permission.AuthenticatedRole); +// +// DatasetWizardModel dataset = new DatasetWizardModel().fromDataModel(this.datasetManager.createOrUpdate(profile)); +//// dataset.setTags(profile.getTags()); //TODO +// return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(dataset)); +// } @Transactional @RequestMapping(method = RequestMethod.GET, value = {"/makepublic/{id}"}, produces = "application/json") diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DescriptionController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DescriptionController.java index d69de9de3..788723f12 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DescriptionController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DescriptionController.java @@ -1,16 +1,15 @@ package eu.eudat.controllers.v2; +import com.fasterxml.jackson.core.JsonProcessingException; import eu.eudat.audit.AuditableAction; import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.commons.enums.DmpAccessType; import eu.eudat.commons.enums.DmpStatus; import eu.eudat.commons.enums.IsActive; -import eu.eudat.data.DescriptionEntity; import eu.eudat.model.Description; import eu.eudat.model.Dmp; import eu.eudat.model.PublicDescription; import eu.eudat.model.builder.DescriptionBuilder; -import eu.eudat.model.builder.PublicDescriptionBuilder; import eu.eudat.model.censorship.DescriptionCensor; import eu.eudat.model.censorship.PublicDescriptionCensor; import eu.eudat.model.persist.DescriptionPersist; @@ -146,7 +145,7 @@ public class DescriptionController { @PostMapping("persist") @Transactional - public Description persist(@MyValidate @RequestBody DescriptionPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { + public Description persist(@MyValidate @RequestBody DescriptionPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JsonProcessingException { logger.debug(new MapLogEntry("persisting" + Description.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); Description persisted = this.descriptionService.persist(model, fieldSet);