argos/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java

608 lines
31 KiB
Java
Raw Normal View History

package eu.eudat.service.description;
2023-11-15 16:06:49 +01:00
import com.fasterxml.jackson.core.JsonProcessingException;
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.authorization.Permission;
import eu.eudat.commons.JsonHandlingService;
2023-11-15 16:06:49 +01:00
import eu.eudat.commons.XmlHandlingService;
import eu.eudat.commons.enums.ContactInfoType;
import eu.eudat.commons.enums.DescriptionStatus;
2023-12-04 17:38:23 +01:00
import eu.eudat.commons.enums.DmpStatus;
import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.enums.notification.NotificationContactType;
import eu.eudat.commons.scope.user.UserScope;
2023-11-15 16:06:49 +01:00
import eu.eudat.commons.types.description.FieldEntity;
import eu.eudat.commons.types.description.PropertyDefinitionEntity;
import eu.eudat.commons.types.notification.*;
2023-11-15 16:06:49 +01:00
import eu.eudat.commons.types.reference.DefinitionEntity;
import eu.eudat.configurations.notification.NotificationProperties;
import eu.eudat.convention.ConventionService;
2023-11-15 16:06:49 +01:00
import eu.eudat.data.*;
import eu.eudat.errorcode.ErrorThesaurusProperties;
import eu.eudat.event.DescriptionTouchedEvent;
import eu.eudat.event.EventBroker;
import eu.eudat.integrationevent.outbox.notification.NotificationIntegrationEvent;
import eu.eudat.integrationevent.outbox.notification.NotificationIntegrationEventHandler;
2023-12-06 17:33:01 +01:00
import eu.eudat.model.*;
import eu.eudat.model.builder.DescriptionBuilder;
import eu.eudat.model.deleter.DescriptionDeleter;
2023-11-15 16:06:49 +01:00
import eu.eudat.model.deleter.DescriptionReferenceDeleter;
import eu.eudat.model.deleter.DescriptionTagDeleter;
2023-12-18 11:55:19 +01:00
import eu.eudat.model.file.FileEnvelope;
import eu.eudat.model.persist.DescriptionPersist;
2023-11-15 16:06:49 +01:00
import eu.eudat.model.persist.DescriptionReferencePersist;
2023-12-04 17:38:23 +01:00
import eu.eudat.model.persist.DescriptionStatusPersist;
2023-11-15 16:06:49 +01:00
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.*;
2024-01-09 15:02:12 +01:00
import eu.eudat.service.elastic.ElasticService;
2023-12-18 11:55:19 +01:00
import eu.eudat.service.transformer.FileTransformerService;
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.Ordering;
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;
2023-11-15 16:06:49 +01:00
import org.jetbrains.annotations.NotNull;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
2023-12-18 11:55:19 +01:00
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import javax.management.InvalidApplicationException;
2023-11-14 12:41:57 +01:00
import java.io.IOException;
2023-12-18 11:55:19 +01:00
import java.nio.file.Files;
import java.time.Instant;
2023-12-06 17:33:01 +01:00
import java.util.*;
2023-11-15 16:06:49 +01:00
import java.util.stream.Collectors;
@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;
private final UserScope userScope;
2023-11-15 16:06:49 +01:00
private final XmlHandlingService xmlHandlingService;
2023-12-18 11:55:19 +01:00
private final FileTransformerService fileTransformerService;
private final NotificationIntegrationEventHandler eventHandler;
private final NotificationProperties notificationProperties;
2024-01-09 15:02:12 +01:00
private final ElasticService elasticService;
@Autowired
public DescriptionServiceImpl(
2024-01-09 15:02:12 +01:00
EntityManager entityManager,
AuthorizationService authorizationService,
DeleterFactory deleterFactory,
BuilderFactory builderFactory,
ConventionService conventionService,
ErrorThesaurusProperties errors,
MessageSource messageSource,
EventBroker eventBroker,
QueryFactory queryFactory,
JsonHandlingService jsonHandlingService,
UserScope userScope,
XmlHandlingService xmlHandlingService, NotificationIntegrationEventHandler eventHandler, NotificationProperties notificationProperties, FileTransformerService fileTransformerService, ElasticService elasticService) {
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;
this.userScope = userScope;
2023-11-15 16:06:49 +01:00
this.xmlHandlingService = xmlHandlingService;
this.eventHandler = eventHandler;
this.notificationProperties = notificationProperties;
2023-12-18 11:55:19 +01:00
this.fileTransformerService = fileTransformerService;
2024-01-09 15:02:12 +01:00
this.elasticService = elasticService;
}
2023-11-15 16:06:49 +01:00
//region Persist
@Override
2024-01-09 15:02:12 +01:00
public Description persist(DescriptionPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, IOException {
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());
2023-11-15 16:06:49 +01:00
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());
2023-12-06 17:33:01 +01:00
if (data.getStatus().equals(DescriptionStatus.Finalized)) throw new MyValidationException(this.errors.getDescriptionIsFinalized().getCode(), this.errors.getDescriptionIsFinalized().getMessage());
if (!data.getDmpId().equals(model.getDmpId())) throw new MyValidationException(this.errors.getDmpCanNotChange().getCode(), this.errors.getDmpCanNotChange().getMessage());
if (!data.getDmpDescriptionTemplateId().equals(model.getDmpDescriptionTemplateId())) throw new MyValidationException(this.errors.getDmpDescriptionTemplateCanNotChange().getCode(), this.errors.getDmpDescriptionTemplateCanNotChange().getMessage());
} else {
data = new DescriptionEntity();
data.setId(UUID.randomUUID());
data.setIsActive(IsActive.Active);
data.setCreatedAt(Instant.now());
2023-12-06 17:33:01 +01:00
data.setDmpId(model.getDmpId());
data.setDmpDescriptionTemplateId(model.getDmpDescriptionTemplateId());
}
2023-12-06 17:33:01 +01:00
DmpDescriptionTemplateEntity dmpDescriptionTemplate = this.entityManager.find(DmpDescriptionTemplateEntity.class, data.getDescriptionTemplateId());
if (dmpDescriptionTemplate == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{data.getDescriptionTemplateId(), DmpDescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
DescriptionTemplateEntity descriptionTemplateEntity = this.entityManager.find(DescriptionTemplateEntity.class, model.getDescriptionTemplateId());
if (descriptionTemplateEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getDescriptionTemplateId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!dmpDescriptionTemplate.getDescriptionTemplateGroupId().equals(descriptionTemplateEntity.getGroupId())) throw new MyValidationException(this.errors.getInvalidDescriptionTemplate().getCode(), this.errors.getInvalidDescriptionTemplate().getMessage());
DmpEntity dmp = this.entityManager.find(DmpEntity.class, data.getDmpId());
if (dmp == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{data.getDmpId(), Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (dmp.getStatus().equals(DmpStatus.Finalized) && isUpdate) throw new MyValidationException(this.errors.getDmpIsFinalized().getCode(), this.errors.getDmpIsFinalized().getMessage());
data.setLabel(model.getLabel());
2023-11-15 16:06:49 +01:00
data.setProperties(this.jsonHandlingService.toJson(this.buildPropertyDefinitionEntity(model.getProperties())));
data.setStatus(model.getStatus());
data.setDescription(model.getDescription());
data.setDescriptionTemplateId(model.getDescriptionTemplateId());
data.setUpdatedAt(Instant.now());
2023-11-15 16:06:49 +01:00
if (isUpdate) this.entityManager.merge(data);
else this.entityManager.persist(data);
2023-11-15 16:06:49 +01:00
this.persistTags(data.getId(), model.getTags());
2023-12-06 17:33:01 +01:00
this.persistDescriptionReferences(data.getId(), model.getReferences());
2023-11-15 16:06:49 +01:00
this.entityManager.flush();
2023-12-06 17:33:01 +01:00
if (isUpdate){
this.sendNotification(data);
2023-12-06 17:33:01 +01:00
}
2023-12-06 17:33:01 +01:00
//this.deleteOldFilesAndAddNew(datasetWizardModel, userInfo); //TODO
this.eventBroker.emit(new DescriptionTouchedEvent(data.getId()));
2024-01-09 15:02:12 +01:00
this.elasticService.persistDescription(data);
2023-11-17 18:01:44 +01:00
return this.builderFactory.builder(DescriptionBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(fields, Description._id), data);
2023-12-04 17:38:23 +01:00
}
private void sendNotification(DescriptionEntity description) throws InvalidApplicationException {
List<DmpUserEntity> existingUsers = this.queryFactory.query(DmpUserQuery.class)
.dmpIds(description.getDmpId())
.isActives(IsActive.Active)
.collect();
if (existingUsers == null || existingUsers.size() <= 1){
return;
}
for (DmpUserEntity dmpUser : existingUsers) {
if (!dmpUser.getUserId().equals(this.userScope.getUserIdSafe())){
UserEntity user = this.queryFactory.query(UserQuery.class).ids(dmpUser.getUserId()).first();
if (user != null){
NotificationIntegrationEvent event = new NotificationIntegrationEvent();
event.setUserId(this.userScope.getUserId());
UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).userIds(user.getId());
query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal));
List<ContactPair> contactPairs = new ArrayList<>();
contactPairs.add(new ContactPair(ContactInfoType.Email, query.first().getValue()));
NotificationContactData contactData = new NotificationContactData(contactPairs, null, null);
event.setContactHint(jsonHandlingService.toJsonSafe(contactData));
event.setContactTypeHint(NotificationContactType.EMAIL);
event = this.applyNotificationType(description.getStatus(), event);
NotificationFieldData data = new NotificationFieldData();
List<FieldInfo> fieldInfoList = new ArrayList<>();
fieldInfoList.add(new FieldInfo("{recipient}", DataType.String, user.getName()));
fieldInfoList.add(new FieldInfo("{reasonName}", DataType.String, this.queryFactory.query(UserQuery.class).ids(this.userScope.getUserId()).first().getName()));
fieldInfoList.add(new FieldInfo("{name}", DataType.String, description.getLabel()));
fieldInfoList.add(new FieldInfo("{id}", DataType.String, description.getId().toString()));
data.setFields(fieldInfoList);
event.setData(jsonHandlingService.toJsonSafe(data));
eventHandler.handle(event);
}
}
}
}
private NotificationIntegrationEvent applyNotificationType(DescriptionStatus status, NotificationIntegrationEvent event) {
switch (status) {
case Draft:
2024-01-04 15:25:07 +01:00
event.setNotificationType(notificationProperties.getDescriptionModifiedType());
case Finalized:
2024-01-04 15:25:07 +01:00
event.setNotificationType(notificationProperties.getDescriptionFinalisedType());
default:
throw new MyApplicationException("Unsupported Description Status.");
}
}
2023-12-13 10:42:59 +01:00
// public List<eu.eudat.commons.types.descriptiontemplate.FieldEntity> getFieldById(String id){
// List<eu.eudat.commons.types.descriptiontemplate.FieldEntity> fieldEntities = new ArrayList<>();
// if (id == null || id.isBlank()) return fieldEntities;
// if (this.getFieldSets() != null){
// for (FieldSetEntity fieldSetEntity: this.getFieldSets()) {
// fieldEntities.addAll(fieldSetEntity.getFieldById(id));
// }
// }
// if (this.getSections() != null){
// for (SectionEntity sectionEntity: this.getSections()) {
// fieldEntities.addAll(sectionEntity.getFieldById(id));
// }
// }
// return fieldEntities;
// }
private void descriptionForce(DescriptionEntity description) throws Exception {
2023-12-06 17:33:01 +01:00
List<String> datasetProfileValidators = new LinkedList<>();
DescriptionTemplateEntity descriptionTemplateEntity = this.entityManager.find(DescriptionTemplateEntity.class, description.getDescriptionTemplateId());
if (descriptionTemplateEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{description.getDescriptionTemplateId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
2023-12-13 10:42:59 +01:00
eu.eudat.commons.types.descriptiontemplate.DefinitionEntity descriptionTemplateDefinition = this.xmlHandlingService.fromXml(eu.eudat.commons.types.descriptiontemplate.DefinitionEntity.class, descriptionTemplateEntity.getDefinition());
// DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
2023-12-06 17:33:01 +01:00
// DocumentBuilder builder = builderFactory.newDocumentBuilder();
// Document xmlDocument = builder.parse(new ByteArrayInputStream(profile.getDefinition().getBytes()));
//
// XPath xPath = XPathFactory.newInstance().newXPath();
// String expression = "//validation/@type[.=1]/ancestor::field/@id";
// NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
//
// for (int i = 0; i < nodeList.getLength(); i++) {
// Node node = nodeList.item(i);
// datasetProfileValidators.add(node.getNodeValue());
// }
//
// expression = "//validation/@type[.=1]/ancestor::fieldSet";
// nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
//
//
// JSONObject obj = new JSONObject(description.getProperties());
// VisibilityRuleService visibilityRuleService = new VisibilityRuleServiceImpl();
// visibilityRuleService.setProperties(obj.toMap());
//
// description.setProfile(profile);
// PagedDatasetProfile pagedDatasetProfile = this.getPagedProfile(new DatasetWizardModel(), description);
// visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules());
//
//
// String failedField = null;
//
// for (String validator : datasetProfileValidators) {
// if (obj.has(validator) && isNullOrEmpty(obj.getString(validator)) && isElementVisible(nodeList, validator, visibilityRuleService)) {
// //throw new Exception("Field value of " + validator + " must be filled.");
// failedField = validator;
// break;
// }
// }
// return failedField;
}
2023-12-04 17:38:23 +01:00
@Override
2024-01-09 15:02:12 +01:00
public Description persistStatus(DescriptionStatusPersist model, FieldSet fields) throws IOException {
2023-12-04 17:38:23 +01:00
logger.debug(new MapLogEntry("persisting data dmp").And("model", model).And("fields", fields));
this.authorizationService.authorizeForce(Permission.EditDescription);
DescriptionEntity 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 (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
if (!data.getStatus().equals(model.getStatus())){
2023-12-05 10:32:17 +01:00
if (data.getStatus().equals(DescriptionStatus.Finalized)){
2023-12-04 17:38:23 +01:00
DmpEntity dmpEntity = this.entityManager.find(DmpEntity.class, data.getDmpId());
if (dmpEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{data.getDmpId(), DmpEntity.class.getSimpleName()}, LocaleContextHolder.getLocale()));
2023-12-05 10:32:17 +01:00
if(!dmpEntity.getStatus().equals(DmpStatus.Draft)) throw new MyValidationException(this.errors.getDmpIsFinalized().getCode(), this.errors.getDmpIsFinalized().getMessage());
2023-12-04 17:38:23 +01:00
}
data.setStatus(model.getStatus());
data.setUpdatedAt(Instant.now());
this.entityManager.merge(data);
this.entityManager.flush();
2024-01-09 15:02:12 +01:00
this.elasticService.persistDescription(data);
2023-12-04 17:38:23 +01:00
this.eventBroker.emit(new DescriptionTouchedEvent(data.getId()));
}
return this.builderFactory.builder(DescriptionBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(fields, Description._id), data);
}
2023-11-15 16:06:49 +01:00
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<String> tagLabels) throws InvalidApplicationException {
if (tagLabels == null) tagLabels = new ArrayList<>();
tagLabels = tagLabels.stream().filter(x-> x != null && !x.isBlank()).toList();
List<DescriptionTagEntity> items = this.queryFactory.query(DescriptionTagQuery.class).isActive(IsActive.Active).descriptionIds(id).collect();
List<TagEntity> tagsAlreadyLinked = this.queryFactory.query(TagQuery.class).isActive(IsActive.Active).ids(items.stream().map(DescriptionTagEntity::getTagId).collect(Collectors.toList())).collect();
List<String> tagLabelsToAdd = tagLabels.stream().filter(x-> tagsAlreadyLinked.stream().noneMatch(y-> y.getLabel() != null && y.getLabel().equalsIgnoreCase(x))).toList();
2024-01-03 13:06:26 +01:00
List<TagEntity> existingTags = this.queryFactory.query(TagQuery.class).isActive(IsActive.Active).tags(tagLabelsToAdd).createdByIds(this.userScope.getUserId()).collect();
2023-11-15 16:06:49 +01:00
List<UUID> 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<DescriptionTagEntity> toDelete = items.stream().filter(x-> updatedCreatedIds.stream().noneMatch(y-> y.equals(x.getId()))).collect(Collectors.toList());
this.deleterFactory.deleter(DescriptionTagDeleter.class).delete(toDelete);
}
2023-12-06 17:33:01 +01:00
private void persistDescriptionReferences(UUID id, List<DescriptionReferencePersist> persists) throws InvalidApplicationException {
if (persists == null) persists = new ArrayList<>();
2023-11-15 16:06:49 +01:00
2023-12-06 17:33:01 +01:00
List<DescriptionReferenceEntity> existingItems = this.queryFactory.query(DescriptionReferenceQuery.class).isActive(IsActive.Active).descriptionIds(id).collect();
Map<UUID, ReferenceEntity> existingReferencesMap = this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).ids(persists.stream().filter(x-> x.getReference().getId() != null).map(x-> x.getReference().getId()).toList()).collect()
.stream()
.collect(Collectors.toMap(ReferenceEntity::getId, x-> x));;
2023-11-15 16:06:49 +01:00
List<UUID> updatedCreatedIds = new ArrayList<>();
2023-12-06 17:33:01 +01:00
for (DescriptionReferencePersist persist : persists) {
Boolean isUpdate = this.conventionService.isValidGuid(persist.getId());
2023-11-15 16:06:49 +01:00
DescriptionReferenceEntity data;
if (isUpdate) {
2023-12-06 17:33:01 +01:00
data = this.entityManager.find(DescriptionReferenceEntity.class, persist.getId());
if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{persist.getId(), DescriptionReference.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(persist.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
if (!data.getReferenceId().equals(persist.getReference().getId())) throw new MyValidationException("reference can not changed");
2023-11-15 16:06:49 +01:00
} else {
data = new DescriptionReferenceEntity();
data.setId(UUID.randomUUID());
2023-12-06 17:33:01 +01:00
data.setDescriptionId(id);
2023-11-15 16:06:49 +01:00
data.setCreatedAt(Instant.now());
2023-12-06 17:33:01 +01:00
data.setIsActive(IsActive.Active);
2023-11-15 16:06:49 +01:00
}
2023-12-06 17:33:01 +01:00
ReferenceEntity reference = this.persistReference(existingReferencesMap, persist.getReference());
data.setReferenceId(reference.getId());
data.setUpdatedAt(Instant.now());
2023-11-15 16:06:49 +01:00
if (isUpdate) this.entityManager.merge(data);
else this.entityManager.persist(data);
updatedCreatedIds.add(data.getId());
}
2023-12-06 17:33:01 +01:00
List<DescriptionReferenceEntity> toDelete = existingItems.stream().filter(x-> updatedCreatedIds.stream().noneMatch(y-> y.equals(x.getId()))).collect(Collectors.toList());
2023-11-15 16:06:49 +01:00
this.deleterFactory.deleter(DescriptionReferenceDeleter.class).delete(toDelete);
}
2023-12-06 17:33:01 +01:00
private ReferenceEntity persistReference(Map<UUID, ReferenceEntity> existingReferencesMap , ReferencePersist persist){
Boolean isUpdate = this.conventionService.isValidGuid(persist.getId());
2023-11-15 16:06:49 +01:00
ReferenceEntity data;
if (isUpdate) {
2023-12-06 17:33:01 +01:00
data = this.entityManager.find(ReferenceEntity.class, persist.getId());
if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{persist.getId(), Reference.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(persist.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
2023-11-15 16:06:49 +01:00
} else {
data = new ReferenceEntity();
data.setId(UUID.randomUUID());
data.setCreatedAt(Instant.now());
2023-12-06 17:33:01 +01:00
data.setIsActive(IsActive.Active);
2023-11-15 16:06:49 +01:00
}
2023-12-06 17:33:01 +01:00
data.setDefinition(this.xmlHandlingService.toXmlSafe(this.buildDefinitionEntity(persist.getDefinition())));
2023-11-15 16:06:49 +01:00
data.setUpdatedAt(Instant.now());
2023-12-06 17:33:01 +01:00
data.setReference(persist.getReference());
data.setAbbreviation(persist.getAbbreviation());
data.setSource(persist.getSource());
data.setSourceType(persist.getSourceType());
2023-11-15 16:06:49 +01:00
data.setUpdatedAt(Instant.now());
2023-12-06 17:33:01 +01:00
2023-11-15 16:06:49 +01:00
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
2023-11-14 12:41:57 +01:00
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException, IOException {
logger.debug("deleting description: {}", id);
this.authorizationService.authorizeForce(Permission.DeleteDescription);
2023-11-14 12:41:57 +01:00
this.deleterFactory.deleter(DescriptionDeleter.class).deleteAndSaveByIds(List.of(id), false);
}
2023-11-15 16:06:49 +01:00
//endregion
2023-11-15 16:06:49 +01:00
//region clone
@Override
2024-01-09 15:02:12 +01:00
public void clone(UUID dmpId, UUID descriptionId) throws InvalidApplicationException, IOException {
logger.debug("cloning description: {} with dmp: {}", descriptionId, dmpId);
this.authorizationService.authorizeForce(Permission.CloneDescription);
DescriptionEntity existing = this.queryFactory.query(DescriptionQuery.class).ids(descriptionId).isActive(IsActive.Active).first();
DescriptionEntity newDescription = new DescriptionEntity();
newDescription.setId(UUID.randomUUID());
newDescription.setLabel(existing.getLabel());
newDescription.setDescription(existing.getDescription());
2023-11-10 18:11:15 +01:00
newDescription.setStatus(DescriptionStatus.Draft);
newDescription.setProperties(existing.getProperties());
newDescription.setDmpId(dmpId);
newDescription.setDmpDescriptionTemplateId(existing.getDmpDescriptionTemplateId());
newDescription.setDescriptionTemplateId(existing.getDescriptionTemplateId());
newDescription.setCreatedById(userScope.getUserId());
newDescription.setCreatedAt(Instant.now());
newDescription.setUpdatedAt(Instant.now());
newDescription.setIsActive(IsActive.Active);
this.entityManager.persist(newDescription);
List<DescriptionReferenceEntity> descriptionReferences = this.queryFactory.query(DescriptionReferenceQuery.class)
.descriptionIds(existing.getId())
.isActive(IsActive.Active)
.collect();
List<DescriptionTagEntity> descriptionTags = this.queryFactory.query(DescriptionTagQuery.class)
.descriptionIds(existing.getId())
.isActive(IsActive.Active)
.collect();
for (DescriptionReferenceEntity descriptionReference : descriptionReferences) {
DescriptionReferenceEntity newReference = new DescriptionReferenceEntity();
newReference.setId(UUID.randomUUID());
newReference.setDescriptionId(newDescription.getId());
newReference.setReferenceId(descriptionReference.getReferenceId());
newReference.setCreatedAt(Instant.now());
newReference.setUpdatedAt(Instant.now());
newReference.setIsActive(IsActive.Active);
this.entityManager.persist(newReference);
}
for(DescriptionTagEntity descriptionTag : descriptionTags) {
DescriptionTagEntity newTag = new DescriptionTagEntity();
newTag.setId(UUID.randomUUID());
newTag.setDescriptionId(newDescription.getId());
newTag.setTagId(descriptionTag.getTagId());
newTag.setCreatedAt(Instant.now());
newTag.setUpdatedAt(Instant.now());
newTag.setIsActive(IsActive.Active);
this.entityManager.persist(newTag);
}
2023-11-10 18:11:15 +01:00
this.entityManager.flush();
2024-01-09 15:02:12 +01:00
this.elasticService.persistDescription(newDescription);
}
2023-11-15 16:06:49 +01:00
//endregion
2023-12-18 11:55:19 +01:00
//region file export
@Override
public ResponseEntity<byte[]> export(UUID id, String exportType) throws InvalidApplicationException, IOException {
2023-12-18 11:55:19 +01:00
HttpHeaders headers = new HttpHeaders();
String type = exportType;
2023-12-18 11:55:19 +01:00
FileEnvelope fileEnvelope = this.fileTransformerService.exportDescription(id, type);
headers.add("Content-Disposition", "attachment;filename=" + fileEnvelope.getFilename());
byte[] data = Files.readAllBytes(fileEnvelope.getFile().toPath());
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<>(data, headers, HttpStatus.OK);
2023-12-18 11:55:19 +01:00
}
//endregion
}