package gr.cite.annotation.service.annotation; import gr.cite.annotation.authorization.AuthorizationFlags; import gr.cite.annotation.authorization.OwnedResource; import gr.cite.annotation.authorization.Permission; import gr.cite.annotation.authorization.authorizationcontentresolver.AuthorizationContentResolver; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.user.UserScope; import gr.cite.annotation.data.AnnotationEntity; import gr.cite.annotation.model.Annotation; import gr.cite.annotation.model.builder.AnnotationBuilder; import gr.cite.annotation.model.deleter.AnnotationDeleter; import gr.cite.annotation.model.persist.AnnotationPersist; 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.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 jakarta.transaction.Transactional; import org.slf4j.LoggerFactory; 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.EnumSet; import java.util.List; import java.util.UUID; @Service public class AnnotationServiceImpl implements AnnotationService { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(AnnotationServiceImpl.class)); private final AuthorizationService authorizationService; private final DeleterFactory deleterFactory; private final EntityManager entityManager; private final BuilderFactory builderFactory; private final UserScope userScope; private final AuthorizationContentResolver authorizationContentResolver; private final MessageSource messageSource; public AnnotationServiceImpl( AuthorizationService authorizationService, DeleterFactory deleterFactory, EntityManager entityManager, BuilderFactory builderFactory, UserScope userScope, AuthorizationContentResolver authorizationContentResolver, MessageSource messageSource) { this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; this.entityManager = entityManager; this.builderFactory = builderFactory; this.userScope = userScope; this.authorizationContentResolver = authorizationContentResolver; this.messageSource = messageSource; } @Override @Transactional public Annotation persist(AnnotationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException { logger.debug(new MapLogEntry("persisting annotation").And("model", model).And("fields", fields)); this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.entityAffiliation(model.getEntityId())), Permission.NewAnnotation); AnnotationEntity data = new AnnotationEntity(); data.setId(UUID.randomUUID()); data.setSubjectId(userScope.getUserIdSafe()); data.setEntityId(model.getEntityId()); data.setEntityType(model.getEntityType()); data.setAnchor(model.getAnchor()); data.setPayload(model.getPayload()); data.setThreadId(model.getThreadId()); data.setParentId(model.getParentId()); data.setProtectionType(model.getProtectionType()); data.setTimeStamp(Instant.now()); data.setCreatedAt(Instant.now()); data.setUpdatedAt(Instant.now()); data.setIsActive(IsActive.Active); this.entityManager.persist(data); this.entityManager.flush(); return this.builderFactory.builder(AnnotationBuilder.class).authorize(EnumSet.of(AuthorizationFlags.None)).build(BaseFieldSet.build(fields, Annotation._id), data); } @Override public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { logger.debug("deleting Annotation: {}", id); AnnotationEntity annotation = this.entityManager.find(AnnotationEntity.class, id); if (annotation == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Annotation.class.getSimpleName()}, LocaleContextHolder.getLocale())); this.authorizationService.authorizeAtLeastOneForce(annotation.getSubjectId() != null ? List.of(new OwnedResource(annotation.getSubjectId())) : null, Permission.DeleteAnnotation); this.deleterFactory.deleter(AnnotationDeleter.class).deleteAndSaveByIds(List.of(id)); } }