diff --git a/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java b/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java index b58a00333..75ffc150d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java +++ b/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java @@ -34,6 +34,10 @@ public class EventBroker { this.applicationEventPublisher.publishEvent(event); } + public void emit(DescriptionTouchedEvent event) { + this.applicationEventPublisher.publishEvent(event); + } + public void emit(DescriptionTemplateTypeTouchedEvent event) { this.applicationEventPublisher.publishEvent(event); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DescriptionDeleter.java b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DescriptionDeleter.java new file mode 100644 index 000000000..174647c71 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DescriptionDeleter.java @@ -0,0 +1,81 @@ +package eu.eudat.model.deleter; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.DescriptionEntity; +import eu.eudat.data.DescriptionTemplateTypeEntity; +import eu.eudat.query.DescriptionQuery; +import eu.eudat.query.DescriptionTemplateTypeQuery; +import gr.cite.tools.data.deleter.Deleter; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DescriptionDeleter implements Deleter { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionDeleter.class)); + + private final EntityManager entityManager; + + protected final QueryFactory queryFactory; + + protected final DeleterFactory deleterFactory; + + @Autowired + public DescriptionDeleter( + EntityManager entityManager, + QueryFactory queryFactory, + DeleterFactory deleterFactory + ) { + this.entityManager = entityManager; + this.queryFactory = queryFactory; + this.deleterFactory = deleterFactory; + } + + public void deleteAndSaveByIds(List ids) throws InvalidApplicationException { + logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids)); + List data = this.queryFactory.query(DescriptionQuery.class).ids(ids).collect(); + logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.deleteAndSave(data); + } + + public void deleteAndSave(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.delete(data); + logger.trace("saving changes"); + this.entityManager.flush(); + logger.trace("changes saved"); + } + + public void delete(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + if (data == null || data.isEmpty()) + return; + + Instant now = Instant.now(); + + for (DescriptionEntity item : data) { + logger.trace("deleting item {}", item.getId()); + item.setIsActive(IsActive.Inactive); + item.setUpdatedAt(now); + logger.trace("updating item"); + this.entityManager.merge(item); + logger.trace("updated item"); + } + } + +} 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 new file mode 100644 index 000000000..32c05a2e0 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java @@ -0,0 +1,20 @@ +package eu.eudat.service.description; + +import eu.eudat.model.Description; +import eu.eudat.model.persist.DescriptionPersist; +import gr.cite.tools.exception.MyApplicationException; +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 javax.management.InvalidApplicationException; +import java.util.UUID; + +public interface DescriptionService { + + Description persist(DescriptionPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException; + + void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException; + +} 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 new file mode 100644 index 000000000..9577d1795 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java @@ -0,0 +1,144 @@ +package eu.eudat.service.description; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.authorization.Permission; +import eu.eudat.commons.JsonHandlingService; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DescriptionEntity; +import eu.eudat.data.DmpEntity; +import eu.eudat.errorcode.ErrorThesaurusProperties; +import eu.eudat.event.DescriptionTouchedEvent; +import eu.eudat.event.DmpTouchedEvent; +import eu.eudat.event.EventBroker; +import eu.eudat.model.Description; +import eu.eudat.model.Dmp; +import eu.eudat.model.builder.DescriptionBuilder; +import eu.eudat.model.builder.DmpBuilder; +import eu.eudat.model.deleter.DescriptionDeleter; +import eu.eudat.model.deleter.DmpDeleter; +import eu.eudat.model.persist.DescriptionPersist; +import eu.eudat.service.dmp.DmpServiceImpl; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.exception.MyValidationException; +import gr.cite.tools.fieldset.BaseFieldSet; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Service; + +import javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.List; +import java.util.UUID; + +@Service +public class DescriptionServiceImpl implements DescriptionService { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionServiceImpl.class)); + + private final EntityManager entityManager; + + private final AuthorizationService authorizationService; + + private final DeleterFactory deleterFactory; + + private final BuilderFactory builderFactory; + + private final ConventionService conventionService; + + private final ErrorThesaurusProperties errors; + + private final MessageSource messageSource; + + private final EventBroker eventBroker; + + private final QueryFactory queryFactory; + + private final JsonHandlingService jsonHandlingService; + + @Autowired + public DescriptionServiceImpl( + EntityManager entityManager, + AuthorizationService authorizationService, + DeleterFactory deleterFactory, + BuilderFactory builderFactory, + ConventionService conventionService, + ErrorThesaurusProperties errors, + MessageSource messageSource, + EventBroker eventBroker, + QueryFactory queryFactory, + JsonHandlingService jsonHandlingService) { + this.entityManager = entityManager; + this.authorizationService = authorizationService; + this.deleterFactory = deleterFactory; + this.builderFactory = builderFactory; + this.conventionService = conventionService; + this.errors = errors; + this.messageSource = messageSource; + this.eventBroker = eventBroker; + this.queryFactory = queryFactory; + this.jsonHandlingService = jsonHandlingService; + } + + @Override + public Description persist(DescriptionPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException { + logger.debug(new MapLogEntry("persisting data dmp").And("model", model).And("fields", fields)); + + this.authorizationService.authorizeForce(Permission.EditDescription); + + Boolean isUpdate = this.conventionService.isValidGuid(model.getId()); + + 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())); + } else { + data = new DescriptionEntity(); + data.setId(UUID.randomUUID()); + data.setIsActive(IsActive.Active); + data.setCreatedAt(Instant.now()); + } + + data.setLabel(model.getLabel()); + data.setDmp(model.getDmp()); + data.setUri(model.getUri()); + data.setProperties(model.getProperties()); + data.setProfile(model.getProfile()); + data.setReference(model.getReference()); + data.setStatus(model.getStatus()); + data.setDescription(model.getDescription()); + data.setDmpSectionIndex(model.getDmpSectionIndex()); + data.setUpdatedAt(Instant.now()); + if (isUpdate) + this.entityManager.merge(data); + else + this.entityManager.persist(data); + + this.entityManager.flush(); + + this.eventBroker.emit(new DescriptionTouchedEvent(data.getId())); + return this.builderFactory.builder(DescriptionBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(BaseFieldSet.build(fields, Description._id), data); + } + + @Override + public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { + logger.debug("deleting description: {}", id); + + this.authorizationService.authorizeForce(Permission.DeleteDescription); + + this.deleterFactory.deleter(DescriptionDeleter.class).deleteAndSaveByIds(List.of(id)); + } +}