2023-10-23 10:31:07 +02:00
package eu.eudat.service.dmp ;
2023-11-02 14:55:17 +01:00
import com.fasterxml.jackson.core.JsonProcessingException ;
2023-10-23 11:51:11 +02:00
import eu.eudat.authorization.AuthorizationFlags ;
import eu.eudat.authorization.Permission ;
2024-03-13 16:45:25 +01:00
import eu.eudat.authorization.authorizationcontentresolver.AuthorizationContentResolver ;
2023-10-23 11:51:11 +02:00
import eu.eudat.commons.JsonHandlingService ;
2023-11-03 15:02:47 +01:00
import eu.eudat.commons.XmlHandlingService ;
2023-11-14 17:18:20 +01:00
import eu.eudat.commons.enums.* ;
2023-12-14 13:02:30 +01:00
import eu.eudat.commons.enums.notification.NotificationContactType ;
2023-11-08 10:45:33 +01:00
import eu.eudat.commons.scope.user.UserScope ;
2023-12-14 13:02:30 +01:00
import eu.eudat.commons.types.actionconfirmation.DmpInvitationEntity ;
2023-11-21 13:26:14 +01:00
import eu.eudat.commons.types.dmp.DmpBlueprintValueEntity ;
import eu.eudat.commons.types.dmp.DmpContactEntity ;
import eu.eudat.commons.types.dmp.DmpPropertiesEntity ;
2024-02-08 17:27:54 +01:00
import eu.eudat.commons.types.dmpblueprint.ReferenceTypeFieldEntity ;
2024-01-12 14:00:34 +01:00
import eu.eudat.commons.types.dmpreference.DmpReferenceDataEntity ;
2023-12-14 13:02:30 +01:00
import eu.eudat.commons.types.notification.* ;
2023-11-03 15:02:47 +01:00
import eu.eudat.commons.types.reference.DefinitionEntity ;
import eu.eudat.commons.types.reference.FieldEntity ;
2023-12-14 13:02:30 +01:00
import eu.eudat.configurations.notification.NotificationProperties ;
2023-10-23 11:51:11 +02:00
import eu.eudat.convention.ConventionService ;
2023-11-06 16:42:12 +01:00
import eu.eudat.data.* ;
2023-10-23 11:51:11 +02:00
import eu.eudat.errorcode.ErrorThesaurusProperties ;
import eu.eudat.event.DmpTouchedEvent ;
import eu.eudat.event.EventBroker ;
2024-03-11 15:02:09 +01:00
import eu.eudat.integrationevent.outbox.annotationentitytouch.AnnotationEntityTouchedIntegrationEventHandler ;
2024-02-21 16:45:48 +01:00
import eu.eudat.integrationevent.outbox.dmptouched.DmpTouchedIntegrationEventHandler ;
2024-01-19 14:12:33 +01:00
import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEvent ;
import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEventHandler ;
2024-02-08 17:12:47 +01:00
import eu.eudat.model.* ;
2023-10-23 11:51:11 +02:00
import eu.eudat.model.builder.DmpBuilder ;
2023-12-04 17:16:57 +01:00
import eu.eudat.model.builder.DmpUserBuilder ;
2023-11-24 11:39:26 +01:00
import eu.eudat.model.deleter.* ;
2023-12-18 11:55:19 +01:00
import eu.eudat.model.file.FileEnvelope ;
2023-11-08 16:13:07 +01:00
import eu.eudat.model.persist.* ;
2023-12-14 13:02:30 +01:00
import eu.eudat.model.persist.actionconfirmation.DmpInvitationPersist ;
2023-11-21 13:26:14 +01:00
import eu.eudat.model.persist.dmpproperties.DmpBlueprintValuePersist ;
import eu.eudat.model.persist.dmpproperties.DmpContactPersist ;
import eu.eudat.model.persist.dmpproperties.DmpPropertiesPersist ;
2024-01-12 14:00:34 +01:00
import eu.eudat.model.persist.dmpreference.DmpReferenceDataPersist ;
2023-11-03 15:02:47 +01:00
import eu.eudat.model.persist.referencedefinition.DefinitionPersist ;
import eu.eudat.model.persist.referencedefinition.FieldPersist ;
2023-11-06 16:42:12 +01:00
import eu.eudat.query.* ;
2023-12-14 13:02:30 +01:00
import eu.eudat.service.actionconfirmation.ActionConfirmationService ;
2023-11-10 15:13:55 +01:00
import eu.eudat.service.description.DescriptionService ;
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 ;
2023-10-23 11:51:11 +02:00
import gr.cite.commons.web.authz.service.AuthorizationService ;
import gr.cite.tools.data.builder.BuilderFactory ;
import gr.cite.tools.data.deleter.DeleterFactory ;
2023-12-14 13:02:30 +01:00
import gr.cite.tools.data.query.Ordering ;
2023-10-23 11:51:11 +02:00
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 ;
2024-03-21 11:12:12 +01:00
import gr.cite.tools.logging.MapLogEntry ;
2024-01-17 10:20:02 +01:00
import gr.cite.tools.validation.ValidatorFactory ;
2023-10-23 11:51:11 +02:00
import jakarta.persistence.EntityManager ;
2023-11-02 17:12:36 +01:00
import jakarta.xml.bind.JAXBException ;
2023-11-03 15:02:47 +01:00
import org.jetbrains.annotations.NotNull ;
2023-10-23 11:51:11 +02:00
import org.slf4j.LoggerFactory ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.context.MessageSource ;
import org.springframework.context.i18n.LocaleContextHolder ;
2023-11-14 10:44:01 +01:00
import org.springframework.http.HttpHeaders ;
import org.springframework.http.HttpStatus ;
import org.springframework.http.MediaType ;
import org.springframework.http.ResponseEntity ;
2023-10-23 11:51:11 +02:00
import org.springframework.stereotype.Service ;
import javax.management.InvalidApplicationException ;
2023-11-14 12:41:57 +01:00
import java.io.IOException ;
2023-10-23 11:51:11 +02:00
import java.time.Instant ;
2023-11-14 10:44:01 +01:00
import java.util.* ;
2023-11-03 15:02:47 +01:00
import java.util.stream.Collectors ;
2023-10-23 11:51:11 +02:00
@Service
2023-10-23 10:31:07 +02:00
public class DmpServiceImpl implements DmpService {
2023-10-23 11:51:11 +02:00
private static final LoggerService logger = new LoggerService ( LoggerFactory . getLogger ( DmpServiceImpl . class ) ) ;
private final EntityManager entityManager ;
private final AuthorizationService authorizationService ;
private final DeleterFactory deleterFactory ;
private final BuilderFactory builderFactory ;
2023-11-02 17:12:36 +01:00
private final QueryFactory queryFactory ;
2023-10-23 11:51:11 +02:00
private final ConventionService conventionService ;
private final ErrorThesaurusProperties errors ;
private final MessageSource messageSource ;
2023-11-03 15:02:47 +01:00
private final XmlHandlingService xmlHandlingService ;
2023-11-02 14:55:17 +01:00
private final JsonHandlingService jsonHandlingService ;
2023-11-08 10:45:33 +01:00
private final UserScope userScope ;
2023-10-23 11:51:11 +02:00
private final EventBroker eventBroker ;
2023-11-10 15:13:55 +01:00
private final DescriptionService descriptionService ;
2023-12-18 11:55:19 +01:00
private final FileTransformerService fileTransformerService ;
2023-11-10 15:13:55 +01:00
2024-01-19 14:12:33 +01:00
private final NotifyIntegrationEventHandler eventHandler ;
2023-12-14 13:02:30 +01:00
private final NotificationProperties notificationProperties ;
private final ActionConfirmationService actionConfirmationService ;
2024-01-19 14:12:33 +01:00
private final gr . cite . tools . validation . ValidatorFactory validatorFactory ;
2024-01-09 15:02:12 +01:00
private final ElasticService elasticService ;
2023-12-21 17:45:49 +01:00
2024-02-21 16:45:48 +01:00
private final DmpTouchedIntegrationEventHandler dmpTouchedIntegrationEventHandler ;
2024-03-11 15:02:09 +01:00
private final AnnotationEntityTouchedIntegrationEventHandler annotationEntityTouchedIntegrationEventHandler ;
2024-03-13 16:45:25 +01:00
private final AuthorizationContentResolver authorizationContentResolver ;
2024-03-11 15:02:09 +01:00
2023-10-23 11:51:11 +02:00
@Autowired
public DmpServiceImpl (
2024-03-13 16:45:25 +01:00
EntityManager entityManager ,
AuthorizationService authorizationService ,
DeleterFactory deleterFactory ,
BuilderFactory builderFactory ,
QueryFactory queryFactory ,
ConventionService conventionService ,
ErrorThesaurusProperties errors ,
MessageSource messageSource ,
XmlHandlingService xmlHandlingService ,
JsonHandlingService jsonHandlingService ,
UserScope userScope ,
EventBroker eventBroker ,
DescriptionService descriptionService ,
NotifyIntegrationEventHandler eventHandler ,
NotificationProperties notificationProperties ,
ActionConfirmationService actionConfirmationService ,
FileTransformerService fileTransformerService ,
ValidatorFactory validatorFactory ,
ElasticService elasticService ,
DmpTouchedIntegrationEventHandler dmpTouchedIntegrationEventHandler ,
AnnotationEntityTouchedIntegrationEventHandler annotationEntityTouchedIntegrationEventHandler , AuthorizationContentResolver authorizationContentResolver ) {
2023-10-23 11:51:11 +02:00
this . entityManager = entityManager ;
this . authorizationService = authorizationService ;
this . deleterFactory = deleterFactory ;
this . builderFactory = builderFactory ;
2023-11-02 17:12:36 +01:00
this . queryFactory = queryFactory ;
2023-10-23 11:51:11 +02:00
this . conventionService = conventionService ;
this . errors = errors ;
this . messageSource = messageSource ;
2023-11-03 15:02:47 +01:00
this . xmlHandlingService = xmlHandlingService ;
2023-11-02 14:55:17 +01:00
this . jsonHandlingService = jsonHandlingService ;
2023-11-08 10:45:33 +01:00
this . userScope = userScope ;
2023-10-23 11:51:11 +02:00
this . eventBroker = eventBroker ;
2023-11-10 15:13:55 +01:00
this . descriptionService = descriptionService ;
2023-12-18 11:55:19 +01:00
this . fileTransformerService = fileTransformerService ;
2023-12-14 13:02:30 +01:00
this . eventHandler = eventHandler ;
this . notificationProperties = notificationProperties ;
this . actionConfirmationService = actionConfirmationService ;
2023-12-21 17:45:49 +01:00
this . validatorFactory = validatorFactory ;
2024-01-09 15:02:12 +01:00
this . elasticService = elasticService ;
2024-02-21 16:45:48 +01:00
this . dmpTouchedIntegrationEventHandler = dmpTouchedIntegrationEventHandler ;
2024-03-11 15:02:09 +01:00
this . annotationEntityTouchedIntegrationEventHandler = annotationEntityTouchedIntegrationEventHandler ;
2024-03-13 16:45:25 +01:00
this . authorizationContentResolver = authorizationContentResolver ;
2023-10-23 11:51:11 +02:00
}
2024-02-22 12:57:42 +01:00
public Dmp persist ( DmpPersist model , FieldSet fields ) throws MyForbiddenException , MyValidationException , MyApplicationException , MyNotFoundException , InvalidApplicationException , JAXBException , IOException {
2024-03-13 16:45:25 +01:00
Boolean isUpdate = this . conventionService . isValidGuid ( model . getId ( ) ) ;
if ( isUpdate ) this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( model . getId ( ) ) ) , Permission . EditDmp ) ;
else this . authorizationService . authorizeForce ( Permission . NewDmp ) ;
2023-11-03 15:02:47 +01:00
DmpEntity data = this . patchAndSave ( model ) ;
2023-10-23 11:51:11 +02:00
2024-02-08 17:12:47 +01:00
DmpBlueprintEntity blueprintEntity = this . entityManager . find ( DmpBlueprintEntity . class , data . getBlueprintId ( ) ) ;
if ( blueprintEntity = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { data . getBlueprintId ( ) , DmpBlueprint . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
eu . eudat . commons . types . dmpblueprint . DefinitionEntity definition = this . xmlHandlingService . fromXmlSafe ( eu . eudat . commons . types . dmpblueprint . DefinitionEntity . class , blueprintEntity . getDefinition ( ) ) ;
if ( definition = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { data . getBlueprintId ( ) , eu . eudat . commons . types . dmpblueprint . DefinitionEntity . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
this . patchAndSaveReferences ( this . buildDmpReferencePersists ( model . getProperties ( ) ) , data . getId ( ) , definition ) ;
2023-11-06 16:42:12 +01:00
2024-03-26 17:44:59 +01:00
if ( isUpdate ) this . checkIfDescriptionTemplateIsUse ( model . getDescriptionTemplates ( ) , model . getId ( ) ) ;
2023-11-24 11:39:26 +01:00
this . patchAndSaveTemplates ( data . getId ( ) , model . getDescriptionTemplates ( ) ) ;
2023-10-23 11:51:11 +02:00
2024-03-21 17:44:19 +01:00
if ( ! isUpdate & & userScope . isSet ( ) ) {
2024-03-14 10:23:46 +01:00
this . addOwner ( data ) ;
if ( model . getUsers ( ) = = null ) model . setUsers ( new ArrayList < > ( ) ) ;
if ( model . getUsers ( ) . stream ( ) . noneMatch ( x - > x . getUser ( ) ! = null & & x . getUser ( ) . equals ( this . userScope . getUserIdSafe ( ) ) & & DmpUserRole . Owner . equals ( x . getRole ( ) ) ) ) model . getUsers ( ) . add ( this . createOwnerPersist ( ) ) ;
}
2023-10-23 11:51:11 +02:00
this . eventBroker . emit ( new DmpTouchedEvent ( data . getId ( ) ) ) ;
2023-11-03 15:02:47 +01:00
2024-02-21 16:45:48 +01:00
this . dmpTouchedIntegrationEventHandler . handle ( DmpTouchedIntegrationEventHandler . buildEventFromPersistModel ( model ) ) ;
2024-03-11 15:02:09 +01:00
this . annotationEntityTouchedIntegrationEventHandler . handle ( AnnotationEntityTouchedIntegrationEventHandler . buildEventFromPersistModel ( model ) ) ;
2023-12-14 13:02:30 +01:00
this . sendNotification ( data ) ;
2024-03-21 17:44:19 +01:00
this . assignUsers ( data . getId ( ) , this . inviteUserOrAssignUsers ( data . getId ( ) , model . getUsers ( ) , false ) , null , false ) ;
2024-03-12 17:47:57 +01:00
this . elasticService . persistDmp ( data ) ;
2024-02-22 12:57:42 +01:00
2024-03-12 17:27:16 +01:00
return this . builderFactory . builder ( DmpBuilder . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . build ( BaseFieldSet . build ( fields , Dmp . _id , Dmp . _hash ) , data ) ;
2023-10-23 11:51:11 +02:00
}
2024-03-26 17:44:59 +01:00
private void checkIfDescriptionTemplateIsUse ( List < DmpDescriptionTemplatePersist > descriptionTemplates , UUID id ) {
List < DmpDescriptionTemplateEntity > existingDmpDescriptionTemplates = this . queryFactory . query ( DmpDescriptionTemplateQuery . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . dmpIds ( id ) . isActive ( IsActive . Active ) . collect ( ) ;
List < DmpDescriptionTemplateEntity > removedDescriptionTemplates = existingDmpDescriptionTemplates . stream ( ) . filter ( x - > descriptionTemplates . stream ( ) . noneMatch ( y - > y . getDescriptionTemplateGroupId ( ) . equals ( x . getDescriptionTemplateGroupId ( ) ) ) ) . collect ( Collectors . toList ( ) ) ;
DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery = this . queryFactory . query ( DmpDescriptionTemplateQuery . class ) . isActive ( IsActive . Active ) . dmpIds ( id ) . descriptionTemplateGroupIds ( removedDescriptionTemplates . stream ( ) . map ( x - > x . getDescriptionTemplateGroupId ( ) ) . collect ( Collectors . toList ( ) ) ) ;
DescriptionQuery query = this . queryFactory . query ( DescriptionQuery . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . dmpDescriptionTemplateSubQuery ( dmpDescriptionTemplateQuery ) . isActive ( IsActive . Active ) ;
if ( query ! = null & & query . count ( ) > 0 ) throw new MyValidationException ( this . errors . getDmpDescriptionTemplateCanNotRemove ( ) . getCode ( ) , this . errors . getDmpDescriptionTemplateCanNotRemove ( ) . getMessage ( ) ) ;
}
2024-03-14 10:23:46 +01:00
private DmpUserPersist createOwnerPersist ( ) {
DmpUserPersist persist = new DmpUserPersist ( ) ;
persist . setRole ( DmpUserRole . Owner ) ;
persist . setUser ( userScope . getUserIdSafe ( ) ) ;
return persist ;
}
2024-03-12 17:47:57 +01:00
private void addOwner ( DmpEntity dmpEntity ) throws InvalidApplicationException {
DmpUserEntity data = new DmpUserEntity ( ) ;
data . setId ( UUID . randomUUID ( ) ) ;
data . setIsActive ( IsActive . Active ) ;
data . setCreatedAt ( Instant . now ( ) ) ;
data . setUpdatedAt ( Instant . now ( ) ) ;
data . setRole ( DmpUserRole . Owner ) ;
data . setUserId ( userScope . getUserId ( ) ) ;
data . setDmpId ( dmpEntity . getId ( ) ) ;
this . entityManager . persist ( data ) ;
}
2023-12-14 13:02:30 +01:00
private void sendNotification ( DmpEntity dmp ) throws InvalidApplicationException {
List < DmpUserEntity > existingUsers = this . queryFactory . query ( DmpUserQuery . class )
. dmpIds ( dmp . getId ( ) )
. 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 ) {
2024-01-10 16:46:45 +01:00
this . createDmpNotificationEvent ( dmp , user , NotificationContactType . EMAIL ) ;
this . createDmpNotificationEvent ( dmp , user , NotificationContactType . IN_APP ) ;
2023-12-14 13:02:30 +01:00
}
}
}
}
2024-01-10 16:46:45 +01:00
private void createDmpNotificationEvent ( DmpEntity dmp , UserEntity user , NotificationContactType type ) throws InvalidApplicationException {
2024-01-19 14:12:33 +01:00
NotifyIntegrationEvent event = new NotifyIntegrationEvent ( ) ;
2024-01-10 16:46:45 +01:00
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 ( type ) ;
2024-02-06 11:27:47 +01:00
this . applyNotificationType ( dmp . getStatus ( ) , event ) ;
2024-01-10 16:46:45 +01:00
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 , dmp . getLabel ( ) ) ) ;
fieldInfoList . add ( new FieldInfo ( " {id} " , DataType . String , dmp . getId ( ) . toString ( ) ) ) ;
data . setFields ( fieldInfoList ) ;
event . setData ( jsonHandlingService . toJsonSafe ( data ) ) ;
eventHandler . handle ( event ) ;
}
2024-02-06 11:27:47 +01:00
private void applyNotificationType ( DmpStatus status , NotifyIntegrationEvent event ) {
2023-12-14 13:02:30 +01:00
switch ( status ) {
case Draft :
2024-01-04 15:25:07 +01:00
event . setNotificationType ( notificationProperties . getDmpModifiedType ( ) ) ;
2024-02-06 11:27:47 +01:00
break ;
2023-12-14 13:02:30 +01:00
case Finalized :
2024-01-04 15:25:07 +01:00
event . setNotificationType ( notificationProperties . getDmpFinalisedType ( ) ) ;
2024-02-06 11:27:47 +01:00
break ;
2023-12-14 13:02:30 +01:00
default :
2023-12-15 09:15:00 +01:00
throw new MyApplicationException ( " Unsupported Dmp Status. " ) ;
2023-12-14 13:02:30 +01:00
}
}
2023-11-14 12:41:57 +01:00
public void deleteAndSave ( UUID id ) throws MyForbiddenException , InvalidApplicationException , IOException {
2023-10-23 11:51:11 +02:00
logger . debug ( " deleting dmp: {} " , id ) ;
2024-03-14 10:23:46 +01:00
this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( id ) ) , Permission . DeleteDmp ) ;
2024-03-21 11:12:12 +01:00
DmpEntity data = this . entityManager . find ( DmpEntity . class , id ) ;
if ( data = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { id , Dmp . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
EntityDoiQuery entityDoiQuery = this . queryFactory . query ( EntityDoiQuery . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . types ( EntityType . DMP ) . entityIds ( data . getId ( ) ) ;
if ( entityDoiQuery . count ( ) > 0 ) throw new MyApplicationException ( " DMP is deposited can not deleted " ) ;
DmpEntity previousFinalized = null ;
if ( data . getVersionStatus ( ) . equals ( DmpVersionStatus . Current ) ) {
DmpQuery dmpQuery = this . queryFactory . query ( DmpQuery . class )
. statuses ( DmpStatus . Finalized )
. excludedIds ( data . getId ( ) )
. isActive ( IsActive . Active )
. groupIds ( data . getGroupId ( ) ) ;
dmpQuery . setOrder ( new Ordering ( ) . addDescending ( Dmp . _version ) ) ;
previousFinalized = dmpQuery . first ( ) ;
if ( previousFinalized ! = null ) {
previousFinalized . setVersionStatus ( DmpVersionStatus . Current ) ;
this . entityManager . merge ( previousFinalized ) ;
}
data . setVersionStatus ( DmpVersionStatus . NotFinalized ) ;
this . entityManager . merge ( data ) ;
this . entityManager . flush ( ) ;
}
2023-11-14 12:41:57 +01:00
this . deleterFactory . deleter ( DmpDeleter . class ) . deleteAndSaveByIds ( List . of ( id ) , false ) ;
2024-03-21 11:12:12 +01:00
if ( previousFinalized ! = null ) this . elasticService . persistDmp ( previousFinalized ) ;
2023-10-23 11:51:11 +02:00
}
2023-11-02 17:12:36 +01:00
@Override
2024-03-21 11:12:12 +01:00
public Dmp createNewVersion ( NewVersionDmpPersist model , FieldSet fields ) throws MyForbiddenException , MyValidationException , MyApplicationException , MyNotFoundException , InvalidApplicationException , IOException {
logger . debug ( new MapLogEntry ( " persisting data bew version " ) . And ( " model " , model ) . And ( " fields " , fields ) ) ;
2024-03-14 10:23:46 +01:00
this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( model . getId ( ) ) ) , Permission . CreateNewVersionDmp ) ;
2023-11-02 17:12:36 +01:00
DmpEntity oldDmpEntity = this . entityManager . find ( DmpEntity . class , model . getId ( ) ) ;
if ( oldDmpEntity = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { model . getId ( ) , Dmp . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
if ( ! this . conventionService . hashValue ( oldDmpEntity . getUpdatedAt ( ) ) . equals ( model . getHash ( ) ) ) throw new MyValidationException ( this . errors . getHashConflict ( ) . getCode ( ) , this . errors . getHashConflict ( ) . getMessage ( ) ) ;
2024-03-21 11:12:12 +01:00
List < DmpEntity > latestVersionDmps = this . queryFactory . query ( DmpQuery . class )
. groupIds ( oldDmpEntity . getGroupId ( ) )
. isActive ( IsActive . Active )
. versionStatuses ( DmpVersionStatus . Current )
. collect ( ) ;
2023-11-14 17:18:20 +01:00
if ( latestVersionDmps . isEmpty ( ) ) throw new MyValidationException ( " Previous dmp not found " ) ;
if ( latestVersionDmps . size ( ) > 1 ) throw new MyValidationException ( " Multiple previous dmps found " ) ;
2024-01-12 14:00:34 +01:00
if ( ! latestVersionDmps . getFirst ( ) . getVersion ( ) . equals ( oldDmpEntity . getVersion ( ) ) ) {
2023-11-03 15:02:47 +01:00
throw new MyValidationException ( this . errors . getDmpNewVersionConflict ( ) . getCode ( ) , this . errors . getDmpNewVersionConflict ( ) . getMessage ( ) ) ;
2023-11-02 17:12:36 +01:00
}
2024-03-21 11:12:12 +01:00
Long notFinalizedCount = this . queryFactory . query ( DmpQuery . class )
. versionStatuses ( DmpVersionStatus . NotFinalized )
. groupIds ( oldDmpEntity . getGroupId ( ) )
. isActive ( IsActive . Active )
. count ( ) ;
if ( notFinalizedCount > 0 ) throw new MyValidationException ( " Already created draft for this template " ) ;
2023-11-02 17:12:36 +01:00
2023-11-10 15:13:55 +01:00
DmpEntity newDmp = new DmpEntity ( ) ;
newDmp . setId ( UUID . randomUUID ( ) ) ;
newDmp . setIsActive ( IsActive . Active ) ;
newDmp . setCreatedAt ( Instant . now ( ) ) ;
newDmp . setUpdatedAt ( Instant . now ( ) ) ;
newDmp . setGroupId ( oldDmpEntity . getGroupId ( ) ) ;
2024-03-21 11:12:12 +01:00
newDmp . setVersionStatus ( DmpVersionStatus . NotFinalized ) ;
2023-11-10 15:13:55 +01:00
newDmp . setVersion ( ( short ) ( oldDmpEntity . getVersion ( ) + 1 ) ) ;
newDmp . setDescription ( model . getDescription ( ) ) ;
newDmp . setLabel ( model . getLabel ( ) ) ;
newDmp . setLanguage ( oldDmpEntity . getLanguage ( ) ) ;
newDmp . setStatus ( DmpStatus . Draft ) ;
newDmp . setProperties ( oldDmpEntity . getProperties ( ) ) ;
2023-11-20 16:09:24 +01:00
newDmp . setBlueprintId ( model . getBlueprintId ( ) ) ;
2024-03-04 11:42:14 +01:00
newDmp . setCreatorId ( this . userScope . getUserId ( ) ) ;
this . entityManager . persist ( newDmp ) ;
2023-11-08 16:13:07 +01:00
List < DmpUserEntity > dmpUsers = this . queryFactory . query ( DmpUserQuery . class )
. dmpIds ( model . getId ( ) )
. isActives ( IsActive . Active )
. collect ( ) ;
List < DmpReferenceEntity > dmpReferences = this . queryFactory . query ( DmpReferenceQuery . class )
. dmpIds ( model . getId ( ) )
. isActives ( IsActive . Active )
. collect ( ) ;
2023-11-10 15:13:55 +01:00
List < DmpDescriptionTemplateEntity > dmpDescriptionTemplates = this . queryFactory . query ( DmpDescriptionTemplateQuery . class )
. dmpIds ( model . getId ( ) )
. isActive ( IsActive . Active )
. collect ( ) ;
2023-11-08 16:13:07 +01:00
for ( DmpUserEntity dmpUser : dmpUsers ) {
DmpUserEntity newUser = new DmpUserEntity ( ) ;
newUser . setId ( UUID . randomUUID ( ) ) ;
2023-12-05 15:05:37 +01:00
newUser . setDmpId ( newDmp . getId ( ) ) ;
2023-11-20 16:09:24 +01:00
newUser . setUserId ( dmpUser . getUserId ( ) ) ;
2023-11-08 16:13:07 +01:00
newUser . setRole ( dmpUser . getRole ( ) ) ;
newUser . setCreatedAt ( Instant . now ( ) ) ;
newUser . setUpdatedAt ( Instant . now ( ) ) ;
newUser . setIsActive ( IsActive . Active ) ;
this . entityManager . persist ( newUser ) ;
}
for ( DmpReferenceEntity dmpReference : dmpReferences ) {
DmpReferenceEntity newReference = new DmpReferenceEntity ( ) ;
newReference . setId ( UUID . randomUUID ( ) ) ;
2023-11-10 15:13:55 +01:00
newReference . setDmpId ( newDmp . getId ( ) ) ;
2023-11-08 16:13:07 +01:00
newReference . setReferenceId ( dmpReference . getReferenceId ( ) ) ;
newReference . setData ( dmpReference . getData ( ) ) ;
newReference . setCreatedAt ( Instant . now ( ) ) ;
newReference . setUpdatedAt ( Instant . now ( ) ) ;
newReference . setIsActive ( IsActive . Active ) ;
this . entityManager . persist ( newReference ) ;
}
2023-11-02 17:12:36 +01:00
2023-11-10 15:13:55 +01:00
for ( DmpDescriptionTemplateEntity dmpDescriptionTemplate : dmpDescriptionTemplates ) {
DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity ( ) ;
newTemplate . setId ( UUID . randomUUID ( ) ) ;
newTemplate . setDmpId ( newDmp . getId ( ) ) ;
2023-11-24 11:39:26 +01:00
newTemplate . setDescriptionTemplateGroupId ( dmpDescriptionTemplate . getDescriptionTemplateGroupId ( ) ) ;
2023-11-10 15:13:55 +01:00
newTemplate . setSectionId ( dmpDescriptionTemplate . getSectionId ( ) ) ;
newTemplate . setCreatedAt ( Instant . now ( ) ) ;
newTemplate . setUpdatedAt ( Instant . now ( ) ) ;
newTemplate . setIsActive ( IsActive . Active ) ;
this . entityManager . persist ( newTemplate ) ;
}
for ( UUID descriptionId : model . getDescriptions ( ) ) {
this . descriptionService . clone ( newDmp . getId ( ) , descriptionId ) ;
}
2023-11-14 17:18:20 +01:00
2023-11-02 17:12:36 +01:00
this . entityManager . flush ( ) ;
2024-03-21 11:12:12 +01:00
this . updateVersionStatusAndSave ( newDmp , DmpStatus . Draft , newDmp . getStatus ( ) ) ;
2024-01-09 15:02:12 +01:00
2024-03-21 11:12:12 +01:00
this . entityManager . flush ( ) ;
2024-01-09 15:02:12 +01:00
this . elasticService . persistDmp ( oldDmpEntity ) ;
this . elasticService . persistDmp ( newDmp ) ;
2023-11-10 15:13:55 +01:00
return this . builderFactory . builder ( DmpBuilder . class ) . build ( BaseFieldSet . build ( fields , Dmp . _id ) , newDmp ) ;
2023-11-02 17:12:36 +01:00
}
2024-03-21 11:12:12 +01:00
private void updateVersionStatusAndSave ( DmpEntity data , DmpStatus previousStatus , DmpStatus newStatus ) {
if ( previousStatus . equals ( newStatus ) )
return ;
if ( previousStatus . equals ( DmpStatus . Finalized ) & & newStatus . equals ( DmpStatus . Draft ) ) {
boolean alreadyCreatedNewVersion = this . queryFactory . query ( DmpQuery . class )
. versionStatuses ( DmpVersionStatus . NotFinalized , DmpVersionStatus . Current )
. excludedIds ( data . getId ( ) )
. isActive ( IsActive . Active )
. groupIds ( data . getGroupId ( ) )
. count ( ) > 0 ;
if ( alreadyCreatedNewVersion ) throw new MyValidationException ( " Already new version is created " ) ;
data . setVersionStatus ( DmpVersionStatus . NotFinalized ) ;
this . entityManager . merge ( data ) ;
}
if ( newStatus . equals ( DmpStatus . Finalized ) ) {
List < DmpEntity > latestVersionDmps = this . queryFactory . query ( DmpQuery . class )
. versionStatuses ( DmpVersionStatus . Current ) . isActive ( IsActive . Active ) . groupIds ( data . getGroupId ( ) ) . collect ( ) ;
if ( latestVersionDmps . size ( ) > 1 )
throw new MyValidationException ( " Multiple previous template found " ) ;
DmpEntity oldDmpEntity = latestVersionDmps . stream ( ) . findFirst ( ) . orElse ( null ) ;
data . setVersionStatus ( DmpVersionStatus . Current ) ;
if ( oldDmpEntity ! = null ) {
data . setVersion ( ( short ) ( oldDmpEntity . getVersion ( ) + 1 ) ) ;
oldDmpEntity . setVersionStatus ( DmpVersionStatus . Previous ) ;
this . entityManager . merge ( oldDmpEntity ) ;
} else {
data . setVersion ( ( short ) 1 ) ;
}
}
}
2023-11-09 13:10:32 +01:00
@Override
2024-03-04 11:42:14 +01:00
public Dmp buildClone ( CloneDmpPersist model , FieldSet fields ) throws MyForbiddenException , MyValidationException , MyApplicationException , MyNotFoundException , IOException , InvalidApplicationException {
2024-03-14 10:23:46 +01:00
this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( model . getId ( ) ) ) , Permission . CloneDmp ) ;
2023-11-09 13:10:32 +01:00
2024-03-12 17:27:16 +01:00
DmpEntity existingDmpEntity = this . queryFactory . query ( DmpQuery . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . ids ( model . getId ( ) ) . firstAs ( fields ) ;
2023-11-10 15:13:55 +01:00
if ( ! this . conventionService . isValidGuid ( model . getId ( ) ) | | existingDmpEntity = = null )
throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { model . getId ( ) , Dmp . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
DmpEntity newDmp = new DmpEntity ( ) ;
newDmp . setId ( UUID . randomUUID ( ) ) ;
newDmp . setIsActive ( IsActive . Active ) ;
newDmp . setCreatedAt ( Instant . now ( ) ) ;
newDmp . setUpdatedAt ( Instant . now ( ) ) ;
newDmp . setGroupId ( UUID . randomUUID ( ) ) ;
newDmp . setVersion ( ( short ) 1 ) ;
2024-03-21 11:12:12 +01:00
newDmp . setVersionStatus ( DmpVersionStatus . NotFinalized ) ;
2023-11-10 15:13:55 +01:00
newDmp . setDescription ( model . getDescription ( ) ) ;
newDmp . setLabel ( model . getLabel ( ) ) ;
newDmp . setLanguage ( existingDmpEntity . getLanguage ( ) ) ;
newDmp . setStatus ( DmpStatus . Draft ) ;
newDmp . setProperties ( existingDmpEntity . getProperties ( ) ) ;
2023-11-20 16:09:24 +01:00
newDmp . setBlueprintId ( existingDmpEntity . getBlueprintId ( ) ) ;
2024-03-04 11:42:14 +01:00
newDmp . setAccessType ( existingDmpEntity . getAccessType ( ) ) ;
newDmp . setCreatorId ( this . userScope . getUserId ( ) ) ;
this . entityManager . persist ( newDmp ) ;
2023-11-10 15:13:55 +01:00
List < DmpUserEntity > dmpUsers = this . queryFactory . query ( DmpUserQuery . class )
. dmpIds ( model . getId ( ) )
. isActives ( IsActive . Active )
. collect ( ) ;
List < DmpReferenceEntity > dmpReferences = this . queryFactory . query ( DmpReferenceQuery . class )
. dmpIds ( model . getId ( ) )
. isActives ( IsActive . Active )
. collect ( ) ;
List < DmpDescriptionTemplateEntity > dmpDescriptionTemplates = this . queryFactory . query ( DmpDescriptionTemplateQuery . class )
. dmpIds ( model . getId ( ) )
. isActive ( IsActive . Active )
. collect ( ) ;
for ( DmpUserEntity dmpUser : dmpUsers ) {
DmpUserEntity newUser = new DmpUserEntity ( ) ;
newUser . setId ( UUID . randomUUID ( ) ) ;
2023-12-05 15:05:37 +01:00
newUser . setDmpId ( newDmp . getId ( ) ) ;
2023-11-20 16:09:24 +01:00
newUser . setUserId ( dmpUser . getUserId ( ) ) ;
2023-11-10 15:13:55 +01:00
newUser . setRole ( dmpUser . getRole ( ) ) ;
newUser . setCreatedAt ( Instant . now ( ) ) ;
newUser . setUpdatedAt ( Instant . now ( ) ) ;
newUser . setIsActive ( IsActive . Active ) ;
this . entityManager . persist ( newUser ) ;
}
for ( DmpReferenceEntity dmpReference : dmpReferences ) {
DmpReferenceEntity newReference = new DmpReferenceEntity ( ) ;
newReference . setId ( UUID . randomUUID ( ) ) ;
newReference . setDmpId ( newDmp . getId ( ) ) ;
newReference . setReferenceId ( dmpReference . getReferenceId ( ) ) ;
newReference . setData ( dmpReference . getData ( ) ) ;
newReference . setCreatedAt ( Instant . now ( ) ) ;
newReference . setUpdatedAt ( Instant . now ( ) ) ;
newReference . setIsActive ( IsActive . Active ) ;
this . entityManager . persist ( newReference ) ;
}
for ( DmpDescriptionTemplateEntity dmpDescriptionTemplate : dmpDescriptionTemplates ) {
DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity ( ) ;
newTemplate . setId ( UUID . randomUUID ( ) ) ;
newTemplate . setDmpId ( newDmp . getId ( ) ) ;
2023-11-24 11:39:26 +01:00
newTemplate . setDescriptionTemplateGroupId ( dmpDescriptionTemplate . getDescriptionTemplateGroupId ( ) ) ;
2023-11-10 15:13:55 +01:00
newTemplate . setSectionId ( dmpDescriptionTemplate . getSectionId ( ) ) ;
newTemplate . setCreatedAt ( Instant . now ( ) ) ;
newTemplate . setUpdatedAt ( Instant . now ( ) ) ;
newTemplate . setIsActive ( IsActive . Active ) ;
this . entityManager . persist ( newTemplate ) ;
}
this . entityManager . flush ( ) ;
2024-01-09 15:02:12 +01:00
this . elasticService . persistDmp ( newDmp ) ;
2023-11-10 15:13:55 +01:00
DmpEntity resultingDmpEntity = this . queryFactory . query ( DmpQuery . class ) . ids ( newDmp . getId ( ) ) . firstAs ( fields ) ;
return this . builderFactory . builder ( DmpBuilder . class ) . build ( fields , resultingDmpEntity ) ;
2023-11-09 13:10:32 +01:00
}
2023-11-13 15:46:35 +01:00
@Override
2024-03-19 16:21:50 +01:00
public List < DmpUser > assignUsers ( UUID dmpId , List < DmpUserPersist > model , FieldSet fieldSet , boolean disableDelete ) throws InvalidApplicationException , IOException {
2024-03-13 16:45:25 +01:00
this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( dmpId ) ) , Permission . AssignDmpUsers ) ;
2024-03-22 14:18:51 +01:00
if ( ! disableDelete & & ( model = = null | | model . stream ( ) . noneMatch ( x - > x . getUser ( ) ! = null & & DmpUserRole . Owner . equals ( x . getRole ( ) ) ) ) ) throw new MyApplicationException ( " At least one owner required " ) ;
2024-03-21 17:44:19 +01:00
2024-01-09 15:02:12 +01:00
DmpEntity dmpEntity = this . entityManager . find ( DmpEntity . class , dmpId ) ;
if ( dmpEntity = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { dmpId , Dmp . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
2023-11-13 16:05:25 +01:00
List < DmpUserEntity > existingUsers = this . queryFactory . query ( DmpUserQuery . class )
2024-01-09 15:02:12 +01:00
. dmpIds ( dmpId )
2023-11-13 16:05:25 +01:00
. isActives ( IsActive . Active )
. collect ( ) ;
2023-11-13 15:46:35 +01:00
2023-12-04 17:16:57 +01:00
List < UUID > updatedCreatedIds = new ArrayList < > ( ) ;
2023-11-13 15:46:35 +01:00
for ( DmpUserPersist dmpUser : model ) {
2024-03-21 17:44:19 +01:00
DmpUserEntity dmpUserEntity = existingUsers . stream ( ) . filter ( x - > x . getDmpId ( ) . equals ( dmpId ) & & x . getUserId ( ) . equals ( dmpUser . getUser ( ) ) & & x . getRole ( ) . equals ( dmpUser . getRole ( ) ) & & Objects . equals ( dmpUser . getSectionId ( ) , x . getSectionId ( ) ) ) . findFirst ( ) . orElse ( null ) ;
2023-12-04 17:16:57 +01:00
if ( dmpUserEntity = = null ) {
dmpUserEntity = new DmpUserEntity ( ) ;
dmpUserEntity . setId ( UUID . randomUUID ( ) ) ;
2024-01-09 15:02:12 +01:00
dmpUserEntity . setDmpId ( dmpId ) ;
2023-12-04 17:16:57 +01:00
dmpUserEntity . setUserId ( dmpUser . getUser ( ) ) ;
dmpUserEntity . setRole ( dmpUser . getRole ( ) ) ;
2024-02-21 11:46:24 +01:00
dmpUserEntity . setSectionId ( dmpUser . getSectionId ( ) ) ;
2023-12-04 17:16:57 +01:00
dmpUserEntity . setCreatedAt ( Instant . now ( ) ) ;
dmpUserEntity . setUpdatedAt ( Instant . now ( ) ) ;
dmpUserEntity . setIsActive ( IsActive . Active ) ;
this . entityManager . persist ( dmpUserEntity ) ;
}
2024-03-21 17:44:19 +01:00
updatedCreatedIds . add ( dmpUserEntity . getId ( ) ) ;
2023-11-13 15:46:35 +01:00
}
2024-03-21 17:44:19 +01:00
List < DmpUserEntity > toDelete = existingUsers . stream ( ) . filter ( x - > updatedCreatedIds . stream ( ) . noneMatch ( y - > y . equals ( x . getId ( ) ) ) ) . collect ( Collectors . toList ( ) ) ;
2024-03-19 16:21:50 +01:00
if ( ! toDelete . isEmpty ( ) & & ! disableDelete ) this . deleterFactory . deleter ( DmpUserDeleter . class ) . delete ( toDelete ) ;
2023-11-13 15:46:35 +01:00
this . entityManager . flush ( ) ;
2023-12-04 17:16:57 +01:00
List < DmpUserEntity > persisted = this . queryFactory . query ( DmpUserQuery . class )
2024-01-09 15:02:12 +01:00
. dmpIds ( dmpId )
2023-11-13 16:05:25 +01:00
. isActives ( IsActive . Active )
. collect ( ) ;
2024-01-09 15:02:12 +01:00
this . elasticService . persistDmp ( dmpEntity ) ;
2024-03-12 17:27:16 +01:00
return this . builderFactory . builder ( DmpUserBuilder . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . build ( BaseFieldSet . build ( fieldSet , DmpUser . _id , DmpUser . _hash ) , persisted ) ;
2023-12-04 17:16:57 +01:00
}
@Override
2024-01-09 15:02:12 +01:00
public Dmp removeUser ( DmpUserRemovePersist model , FieldSet fields ) throws InvalidApplicationException , IOException {
2024-03-14 10:23:46 +01:00
this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( model . getDmpId ( ) ) ) , Permission . AssignDmpUsers ) ;
2024-02-22 14:05:09 +01:00
DmpEntity data = this . entityManager . find ( DmpEntity . class , model . getDmpId ( ) ) ;
2023-12-04 17:16:57 +01:00
if ( data = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { model . getId ( ) , Dmp . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
List < DmpUserEntity > existingUsers = this . queryFactory . query ( DmpUserQuery . class )
. dmpIds ( model . getDmpId ( ) ) . ids ( model . getId ( ) ) . userRoles ( model . getRole ( ) )
. collect ( ) ;
if ( ! existingUsers . isEmpty ( ) ) this . deleterFactory . deleter ( DmpUserDeleter . class ) . delete ( existingUsers ) ;
this . entityManager . flush ( ) ;
2024-01-09 15:02:12 +01:00
DmpEntity dmpEntity = this . entityManager . find ( DmpEntity . class , model . getDmpId ( ) ) ;
if ( dmpEntity = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { model . getDmpId ( ) , Dmp . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
this . elasticService . persistDmp ( dmpEntity ) ;
2024-03-12 17:27:16 +01:00
return this . builderFactory . builder ( DmpBuilder . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . build ( BaseFieldSet . build ( fields , Dmp . _id , Dmp . _hash ) , data ) ;
2023-11-13 15:46:35 +01:00
}
2023-11-14 10:44:01 +01:00
@Override
2024-03-11 14:01:56 +01:00
public ResponseEntity < byte [ ] > export ( UUID id , String transformerId , String exportType ) throws InvalidApplicationException , IOException {
2023-11-14 10:44:01 +01:00
HttpHeaders headers = new HttpHeaders ( ) ;
2023-12-18 11:55:19 +01:00
2024-03-11 14:01:56 +01:00
FileEnvelope fileEnvelope = this . fileTransformerService . exportDmp ( id , transformerId , exportType ) ;
2023-12-18 11:55:19 +01:00
headers . add ( " Content-Disposition " , " attachment;filename= " + fileEnvelope . getFilename ( ) ) ;
2024-02-19 16:28:46 +01:00
byte [ ] data = fileEnvelope . getFile ( ) ;
2023-12-19 17:09:09 +01:00
headers . setContentType ( MediaType . APPLICATION_OCTET_STREAM ) ;
return new ResponseEntity < > ( data , headers , HttpStatus . OK ) ;
2023-11-14 10:44:01 +01:00
}
2023-11-10 15:13:55 +01:00
private DmpEntity patchAndSave ( DmpPersist model ) throws JsonProcessingException , InvalidApplicationException {
2023-11-03 15:02:47 +01:00
Boolean isUpdate = this . conventionService . isValidGuid ( model . getId ( ) ) ;
DmpEntity data ;
if ( isUpdate ) {
data = this . entityManager . find ( DmpEntity . class , model . getId ( ) ) ;
if ( data = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { model . getId ( ) , Dmp . 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-11-13 15:46:35 +01:00
if ( model . getStatus ( ) ! = null & & model . getStatus ( ) = = DmpStatus . Finalized & & data . getStatus ( ) ! = DmpStatus . Finalized ) {
2024-03-14 10:23:46 +01:00
this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( model . getId ( ) ) ) , Permission . FinalizeDmp ) ;
2023-11-13 15:46:35 +01:00
data . setStatus ( model . getStatus ( ) ) ;
data . setFinalizedAt ( Instant . now ( ) ) ;
}
2023-11-03 15:02:47 +01:00
} else {
data = new DmpEntity ( ) ;
data . setId ( UUID . randomUUID ( ) ) ;
data . setGroupId ( UUID . randomUUID ( ) ) ;
data . setVersion ( ( short ) 1 ) ;
2023-11-10 15:13:55 +01:00
data . setStatus ( DmpStatus . Draft ) ;
2024-03-21 11:12:12 +01:00
data . setVersionStatus ( DmpVersionStatus . NotFinalized ) ;
2023-11-20 16:09:24 +01:00
data . setCreatorId ( userScope . getUserId ( ) ) ;
data . setBlueprintId ( model . getBlueprint ( ) ) ;
2023-11-03 15:02:47 +01:00
data . setIsActive ( IsActive . Active ) ;
data . setCreatedAt ( Instant . now ( ) ) ;
}
2024-03-21 11:12:12 +01:00
DmpStatus previousStatus = data . getStatus ( ) ;
2023-11-03 15:02:47 +01:00
data . setLabel ( model . getLabel ( ) ) ;
2024-03-12 13:07:47 +01:00
data . setLanguage ( model . getLanguage ( ) ) ;
2023-11-21 13:26:14 +01:00
data . setProperties ( this . jsonHandlingService . toJson ( this . buildDmpPropertiesEntity ( model . getProperties ( ) ) ) ) ;
2023-11-03 15:02:47 +01:00
data . setDescription ( model . getDescription ( ) ) ;
2023-11-10 18:11:15 +01:00
data . setAccessType ( model . getAccessType ( ) ) ;
2023-11-03 15:02:47 +01:00
data . setUpdatedAt ( Instant . now ( ) ) ;
if ( isUpdate )
this . entityManager . merge ( data ) ;
2023-11-08 10:45:33 +01:00
else {
2023-11-03 15:02:47 +01:00
this . entityManager . persist ( data ) ;
2023-11-08 10:45:33 +01:00
}
2023-11-03 15:02:47 +01:00
this . entityManager . flush ( ) ;
2024-03-21 11:12:12 +01:00
this . updateVersionStatusAndSave ( data , previousStatus , data . getStatus ( ) ) ;
this . entityManager . flush ( ) ;
2023-11-03 15:02:47 +01:00
return data ;
}
2023-11-21 13:26:14 +01:00
private @NotNull DmpPropertiesEntity buildDmpPropertiesEntity ( DmpPropertiesPersist persist ) {
DmpPropertiesEntity data = new DmpPropertiesEntity ( ) ;
if ( persist = = null ) return data ;
if ( ! this . conventionService . isListNullOrEmpty ( persist . getContacts ( ) ) ) {
data . setContacts ( new ArrayList < > ( ) ) ;
for ( DmpContactPersist contactPersist : persist . getContacts ( ) ) {
data . getContacts ( ) . add ( this . buildDmpContactEntity ( contactPersist ) ) ;
}
}
2024-01-19 17:28:53 +01:00
if ( persist . getDmpBlueprintValues ( ) ! = null & & ! persist . getDmpBlueprintValues ( ) . isEmpty ( ) ) {
2023-11-21 13:26:14 +01:00
data . setDmpBlueprintValues ( new ArrayList < > ( ) ) ;
2024-01-19 14:12:03 +01:00
for ( DmpBlueprintValuePersist fieldValuePersist : persist . getDmpBlueprintValues ( ) . values ( ) ) {
2024-01-12 14:00:34 +01:00
if ( ! this . conventionService . isNullOrEmpty ( fieldValuePersist . getFieldValue ( ) ) ) data . getDmpBlueprintValues ( ) . add ( this . buildDmpBlueprintValueEntity ( fieldValuePersist ) ) ;
2023-11-21 13:26:14 +01:00
}
}
return data ;
}
private @NotNull DmpContactEntity buildDmpContactEntity ( DmpContactPersist persist ) {
DmpContactEntity data = new DmpContactEntity ( ) ;
if ( persist = = null ) return data ;
data . setEmail ( persist . getEmail ( ) ) ;
data . setLastName ( persist . getLastName ( ) ) ;
data . setFirstName ( persist . getFirstName ( ) ) ;
data . setUserId ( persist . getUserId ( ) ) ;
return data ;
}
private @NotNull DmpBlueprintValueEntity buildDmpBlueprintValueEntity ( DmpBlueprintValuePersist persist ) {
DmpBlueprintValueEntity data = new DmpBlueprintValueEntity ( ) ;
if ( persist = = null ) return data ;
data . setValue ( persist . getFieldValue ( ) ) ;
data . setFieldId ( persist . getFieldId ( ) ) ;
return data ;
}
2023-11-03 15:02:47 +01:00
2024-01-12 14:00:34 +01:00
private @NotNull List < DmpReferencePersist > buildDmpReferencePersists ( DmpPropertiesPersist persist ) {
List < DmpReferencePersist > dmpReferencePersists = new ArrayList < > ( ) ;
2024-01-19 17:28:53 +01:00
if ( persist . getDmpBlueprintValues ( ) ! = null & & ! persist . getDmpBlueprintValues ( ) . isEmpty ( ) ) {
2024-01-19 14:12:03 +01:00
for ( DmpBlueprintValuePersist fieldValuePersist : persist . getDmpBlueprintValues ( ) . values ( ) ) {
2024-01-12 14:00:34 +01:00
if ( this . conventionService . isNullOrEmpty ( fieldValuePersist . getFieldValue ( ) ) & & ! this . conventionService . isListNullOrEmpty ( fieldValuePersist . getReferences ( ) ) ) {
for ( ReferencePersist referencePersist : fieldValuePersist . getReferences ( ) ) {
DmpReferencePersist dmpReferencePersist = new DmpReferencePersist ( ) ;
dmpReferencePersist . setData ( new DmpReferenceDataPersist ( ) ) ;
dmpReferencePersist . getData ( ) . setBlueprintFieldId ( fieldValuePersist . getFieldId ( ) ) ;
dmpReferencePersist . setReference ( referencePersist ) ;
2024-01-18 13:23:20 +01:00
dmpReferencePersists . add ( dmpReferencePersist ) ;
2024-01-12 14:00:34 +01:00
}
}
}
}
return dmpReferencePersists ;
}
2024-02-08 17:12:47 +01:00
private void patchAndSaveReferences ( List < DmpReferencePersist > models , UUID dmpId , eu . eudat . commons . types . dmpblueprint . DefinitionEntity blueprintDefinition ) throws InvalidApplicationException {
2024-01-12 14:00:34 +01:00
if ( models = = null ) models = new ArrayList < > ( ) ;
List < DmpReferenceEntity > dmpReferences = this . queryFactory . query ( DmpReferenceQuery . class ) . dmpIds ( dmpId ) . collect ( ) ;
Map < UUID , List < DmpReferenceEntity > > dmpReferenceEntityByReferenceId = new HashMap < > ( ) ;
for ( DmpReferenceEntity dmpReferenceEntity : dmpReferences ) {
List < DmpReferenceEntity > dmpReferenceEntities = dmpReferenceEntityByReferenceId . getOrDefault ( dmpReferenceEntity . getReferenceId ( ) , null ) ;
if ( dmpReferenceEntities = = null ) {
dmpReferenceEntities = new ArrayList < > ( ) ;
dmpReferenceEntityByReferenceId . put ( dmpReferenceEntity . getReferenceId ( ) , dmpReferenceEntities ) ;
}
dmpReferenceEntities . add ( dmpReferenceEntity ) ;
}
2023-11-03 15:02:47 +01:00
2024-01-12 14:00:34 +01:00
Map < UUID , DmpReferenceDataEntity > dmpReferenceDataEntityMap = new HashMap < > ( ) ;
for ( DmpReferenceEntity dmpReferenceEntity : dmpReferences ) {
2024-01-19 17:28:53 +01:00
dmpReferenceDataEntityMap . put ( dmpReferenceEntity . getId ( ) , this . jsonHandlingService . fromJsonSafe ( DmpReferenceDataEntity . class , dmpReferenceEntity . getData ( ) ) ) ;
2024-01-12 14:00:34 +01:00
}
2023-11-03 15:02:47 +01:00
2024-01-12 14:00:34 +01:00
List < UUID > updatedCreatedIds = new ArrayList < > ( ) ;
2023-11-06 12:31:01 +01:00
for ( DmpReferencePersist model : models ) {
2024-01-12 14:00:34 +01:00
ReferencePersist referencePersist = model . getReference ( ) ;
2024-03-21 11:12:12 +01:00
ReferenceEntity referenceEntity ;
2024-01-12 14:00:34 +01:00
if ( this . conventionService . isValidGuid ( referencePersist . getId ( ) ) ) {
referenceEntity = this . entityManager . find ( ReferenceEntity . class , referencePersist . getId ( ) ) ;
if ( referenceEntity = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { referencePersist . getId ( ) , Reference . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
2023-11-03 15:02:47 +01:00
} else {
2024-02-08 17:27:54 +01:00
ReferenceTypeFieldEntity fieldEntity = blueprintDefinition . getFieldById ( model . getData ( ) . getBlueprintFieldId ( ) ) . stream ( ) . filter ( x - > x . getCategory ( ) . equals ( DmpBlueprintFieldCategory . ReferenceType ) ) . map ( x - > ( ReferenceTypeFieldEntity ) x ) . findFirst ( ) . orElse ( null ) ;
if ( fieldEntity = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { model . getData ( ) . getBlueprintFieldId ( ) , ReferenceTypeFieldEntity . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
2024-02-08 17:12:47 +01:00
referenceEntity = this . queryFactory . query ( ReferenceQuery . class ) . sourceTypes ( referencePersist . getSourceType ( ) ) . typeIds ( fieldEntity . getReferenceTypeId ( ) ) . sources ( referencePersist . getSource ( ) ) . isActive ( IsActive . Active ) . references ( referencePersist . getReference ( ) ) . first ( ) ;
2024-01-12 14:00:34 +01:00
if ( referenceEntity = = null ) {
referenceEntity = new ReferenceEntity ( ) ;
referenceEntity . setId ( UUID . randomUUID ( ) ) ;
2024-02-21 10:03:11 +01:00
referenceEntity . setLabel ( referencePersist . getLabel ( ) ) ;
2024-01-12 14:00:34 +01:00
referenceEntity . setIsActive ( IsActive . Active ) ;
referenceEntity . setCreatedAt ( Instant . now ( ) ) ;
2024-02-08 17:12:47 +01:00
referenceEntity . setTypeId ( fieldEntity . getReferenceTypeId ( ) ) ;
2024-01-12 14:00:34 +01:00
referenceEntity . setDefinition ( this . xmlHandlingService . toXmlSafe ( this . buildDefinitionEntity ( referencePersist . getDefinition ( ) ) ) ) ;
referenceEntity . setUpdatedAt ( Instant . now ( ) ) ;
referenceEntity . setReference ( referencePersist . getReference ( ) ) ;
referenceEntity . setAbbreviation ( referencePersist . getAbbreviation ( ) ) ;
referenceEntity . setSource ( referencePersist . getSource ( ) ) ;
referenceEntity . setSourceType ( referencePersist . getSourceType ( ) ) ;
this . entityManager . persist ( referenceEntity ) ;
}
}
2023-11-03 15:47:54 +01:00
2024-01-12 14:00:34 +01:00
DmpReferenceEntity data = null ;
List < DmpReferenceEntity > dmpReferenceEntities = dmpReferenceEntityByReferenceId . getOrDefault ( referenceEntity . getId ( ) , new ArrayList < > ( ) ) ;
for ( DmpReferenceEntity dmpReferenceEntity : dmpReferenceEntities ) {
DmpReferenceDataEntity dmpReferenceDataEntity = dmpReferenceDataEntityMap . getOrDefault ( dmpReferenceEntity . getId ( ) , new DmpReferenceDataEntity ( ) ) ;
if ( Objects . equals ( dmpReferenceDataEntity . getBlueprintFieldId ( ) , model . getData ( ) . getBlueprintFieldId ( ) ) ) {
data = dmpReferenceEntity ;
break ;
}
2023-11-03 15:02:47 +01:00
}
2024-01-12 14:00:34 +01:00
boolean isUpdate = data ! = null ;
if ( ! isUpdate ) {
data = new DmpReferenceEntity ( ) ;
2024-01-18 13:23:20 +01:00
data . setId ( UUID . randomUUID ( ) ) ;
2024-01-12 14:00:34 +01:00
data . setReferenceId ( referenceEntity . getId ( ) ) ;
data . setDmpId ( dmpId ) ;
data . setCreatedAt ( Instant . now ( ) ) ;
data . setIsActive ( IsActive . Active ) ;
data . setData ( this . jsonHandlingService . toJsonSafe ( this . buildDmpReferenceDataEntity ( model . getData ( ) ) ) ) ;
}
updatedCreatedIds . add ( data . getId ( ) ) ;
2023-11-03 15:02:47 +01:00
data . setUpdatedAt ( Instant . now ( ) ) ;
2024-01-12 14:00:34 +01:00
if ( isUpdate ) this . entityManager . merge ( data ) ;
else this . entityManager . persist ( data ) ;
2023-11-03 15:02:47 +01:00
}
2024-01-12 14:00:34 +01:00
List < DmpReferenceEntity > toDelete = dmpReferences . stream ( ) . filter ( x - > updatedCreatedIds . stream ( ) . noneMatch ( y - > y . equals ( x . getId ( ) ) ) ) . collect ( Collectors . toList ( ) ) ;
this . deleterFactory . deleter ( DmpReferenceDeleter . class ) . delete ( toDelete ) ;
2023-11-03 15:02:47 +01:00
this . entityManager . flush ( ) ;
}
2023-11-06 16:42:12 +01:00
2023-11-24 11:39:26 +01:00
private void patchAndSaveTemplates ( UUID id , List < DmpDescriptionTemplatePersist > models ) throws InvalidApplicationException {
if ( models = = null ) models = new ArrayList < > ( ) ;
List < DmpDescriptionTemplateEntity > items = this . queryFactory . query ( DmpDescriptionTemplateQuery . class ) . isActive ( IsActive . Active ) . dmpIds ( id ) . collect ( ) ;
List < UUID > updatedCreatedIds = new ArrayList < > ( ) ;
2023-11-06 16:42:12 +01:00
for ( DmpDescriptionTemplatePersist model : models ) {
2023-11-24 11:39:26 +01:00
DmpDescriptionTemplateEntity data = items . stream ( ) . filter ( x - > x . getDescriptionTemplateGroupId ( ) . equals ( model . getDescriptionTemplateGroupId ( ) ) & & x . getSectionId ( ) . equals ( model . getSectionId ( ) ) ) . findFirst ( ) . orElse ( null ) ;
if ( data = = null ) {
data = new DmpDescriptionTemplateEntity ( ) ;
data . setId ( UUID . randomUUID ( ) ) ;
data . setIsActive ( IsActive . Active ) ;
data . setCreatedAt ( Instant . now ( ) ) ;
2024-01-19 17:28:53 +01:00
data . setUpdatedAt ( Instant . now ( ) ) ;
2023-11-24 11:39:26 +01:00
data . setDmpId ( id ) ;
data . setSectionId ( model . getSectionId ( ) ) ;
data . setDescriptionTemplateGroupId ( model . getDescriptionTemplateGroupId ( ) ) ;
this . entityManager . persist ( data ) ;
2023-11-06 16:42:12 +01:00
}
2023-11-24 11:39:26 +01:00
updatedCreatedIds . add ( data . getId ( ) ) ;
2023-11-06 16:42:12 +01:00
}
2023-11-24 11:39:26 +01:00
List < DmpDescriptionTemplateEntity > toDelete = items . stream ( ) . filter ( x - > updatedCreatedIds . stream ( ) . noneMatch ( y - > y . equals ( x . getId ( ) ) ) ) . collect ( Collectors . toList ( ) ) ;
this . deleterFactory . deleter ( DmpDescriptionTemplateDeleter . class ) . delete ( toDelete ) ;
2023-11-06 16:42:12 +01:00
}
2023-11-03 15:02:47 +01:00
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 ( FieldPersist fieldPersist : persist . getFields ( ) ) {
2023-11-21 13:26:14 +01:00
data . getFields ( ) . add ( this . buildDmpContactEntity ( fieldPersist ) ) ;
2023-11-03 15:02:47 +01:00
}
}
return data ;
}
2024-01-12 14:00:34 +01:00
private @NotNull DmpReferenceDataEntity buildDmpReferenceDataEntity ( DmpReferenceDataPersist persist ) {
DmpReferenceDataEntity data = new DmpReferenceDataEntity ( ) ;
if ( persist = = null ) return data ;
data . setBlueprintFieldId ( persist . getBlueprintFieldId ( ) ) ;
return data ;
}
2023-11-21 13:26:14 +01:00
private @NotNull FieldEntity buildDmpContactEntity ( FieldPersist persist ) {
2023-11-03 15:02:47 +01:00
FieldEntity data = new FieldEntity ( ) ;
if ( persist = = null ) return data ;
data . setCode ( persist . getCode ( ) ) ;
data . setDataType ( persist . getDataType ( ) ) ;
data . setCode ( persist . getCode ( ) ) ;
return data ;
}
2024-03-15 08:39:36 +01:00
public void finalize ( UUID id , List < UUID > descriptionIds ) throws MyForbiddenException , MyValidationException , MyApplicationException , MyNotFoundException , InvalidApplicationException , IOException {
2024-03-15 10:39:01 +01:00
this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( id ) ) , Permission . FinalizeDmp ) ;
2024-03-15 08:39:36 +01:00
DmpEntity dmp = this . queryFactory . query ( DmpQuery . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . ids ( id ) . isActive ( IsActive . Active ) . first ( ) ;
if ( dmp = = null ) {
throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { id , Dmp . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
}
if ( dmp . getStatus ( ) . equals ( DmpStatus . Finalized ) ) {
throw new MyApplicationException ( " DMP is already finalized " ) ;
}
2024-03-21 11:12:12 +01:00
List < DescriptionEntity > descriptions = this . queryFactory . query ( DescriptionQuery . class )
. authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . dmpIds ( id ) . isActive ( IsActive . Active ) . collect ( ) ;
2024-03-15 10:39:01 +01:00
for ( DescriptionEntity description : descriptions ) {
if ( descriptionIds . contains ( description . getId ( ) ) ) {
// description to be finalized
2024-03-15 08:39:36 +01:00
if ( description . getStatus ( ) . equals ( DescriptionStatus . Finalized ) ) {
throw new MyApplicationException ( " Description is already finalized " ) ;
2024-03-15 10:39:01 +01:00
}
2024-03-21 11:12:12 +01:00
if ( this . descriptionService . validate ( List . of ( description . getId ( ) ) ) . getFirst ( ) . getResult ( ) . equals ( DescriptionValidationOutput . Invalid ) ) {
2024-03-19 12:54:23 +01:00
throw new MyApplicationException ( " Description is invalid " ) ;
}
2024-03-15 08:39:36 +01:00
description . setStatus ( DescriptionStatus . Finalized ) ;
description . setUpdatedAt ( Instant . now ( ) ) ;
description . setFinalizedAt ( Instant . now ( ) ) ;
this . entityManager . merge ( description ) ;
2024-03-15 10:39:01 +01:00
} else if ( description . getStatus ( ) . equals ( DescriptionStatus . Draft ) ) {
// description to be canceled
2024-03-15 08:39:36 +01:00
description . setStatus ( DescriptionStatus . Canceled ) ;
2024-03-15 10:39:01 +01:00
this . deleterFactory . deleter ( DescriptionDeleter . class ) . delete ( List . of ( description ) , true ) ;
2024-03-15 08:39:36 +01:00
}
}
2024-03-21 11:12:12 +01:00
DmpStatus previousStatus = dmp . getStatus ( ) ;
2024-03-15 08:39:36 +01:00
dmp . setStatus ( DmpStatus . Finalized ) ;
dmp . setUpdatedAt ( Instant . now ( ) ) ;
dmp . setFinalizedAt ( Instant . now ( ) ) ;
this . entityManager . merge ( dmp ) ;
this . entityManager . flush ( ) ;
2024-03-21 11:12:12 +01:00
this . updateVersionStatusAndSave ( dmp , previousStatus , dmp . getStatus ( ) ) ;
this . entityManager . flush ( ) ;
2024-03-15 08:39:36 +01:00
this . elasticService . persistDmp ( dmp ) ;
this . sendNotification ( dmp ) ;
}
2024-03-21 11:12:12 +01:00
public void undoFinalize ( UUID id , FieldSet fields ) throws MyForbiddenException , MyValidationException , MyApplicationException , MyNotFoundException , InvalidApplicationException {
2024-03-15 10:39:01 +01:00
this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( id ) ) , Permission . UndoFinalizeDmp ) ;
2024-03-15 08:39:36 +01:00
DmpEntity dmp = this . queryFactory . query ( DmpQuery . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . ids ( id ) . isActive ( IsActive . Active ) . firstAs ( fields ) ;
2024-03-21 11:12:12 +01:00
if ( dmp = = null ) throw new MyNotFoundException ( messageSource . getMessage ( " General_ItemNotFound " , new Object [ ] { id , Dmp . class . getSimpleName ( ) } , LocaleContextHolder . getLocale ( ) ) ) ;
2024-03-15 08:39:36 +01:00
2024-03-21 11:12:12 +01:00
if ( ! dmp . getStatus ( ) . equals ( DmpStatus . Finalized ) ) throw new MyApplicationException ( " DMP is already drafted " ) ;
2024-03-15 08:39:36 +01:00
2024-03-15 10:39:01 +01:00
EntityDoiQuery entityDoiQuery = this . queryFactory . query ( EntityDoiQuery . class ) . authorize ( AuthorizationFlags . OwnerOrDmpAssociatedOrPermission ) . types ( EntityType . DMP ) . entityIds ( dmp . getId ( ) ) ;
2024-03-21 11:12:12 +01:00
if ( entityDoiQuery . count ( ) > 0 ) throw new MyApplicationException ( " DMP is deposited " ) ;
2024-03-15 10:39:01 +01:00
2024-03-15 08:39:36 +01:00
dmp . setStatus ( DmpStatus . Draft ) ;
dmp . setUpdatedAt ( Instant . now ( ) ) ;
this . entityManager . merge ( dmp ) ;
this . entityManager . flush ( ) ;
2024-03-21 11:12:12 +01:00
this . updateVersionStatusAndSave ( dmp , DmpStatus . Finalized , dmp . getStatus ( ) ) ;
this . entityManager . flush ( ) ;
2024-03-15 08:39:36 +01:00
this . sendNotification ( dmp ) ;
}
2023-12-14 13:02:30 +01:00
// invites
2024-03-14 10:23:46 +01:00
public void inviteUserOrAssignUsers ( UUID id , List < DmpUserPersist > users ) throws InvalidApplicationException , JAXBException , IOException {
2024-03-21 17:44:19 +01:00
this . inviteUserOrAssignUsers ( id , users , true ) ;
}
private List < DmpUserPersist > inviteUserOrAssignUsers ( UUID id , List < DmpUserPersist > users , boolean persistUsers ) throws InvalidApplicationException , JAXBException , IOException {
2024-03-14 10:23:46 +01:00
this . authorizationService . authorizeAtLeastOneForce ( List . of ( this . authorizationContentResolver . dmpAffiliation ( id ) ) , Permission . InviteDmpUsers ) ;
2023-12-14 13:02:30 +01:00
DmpEntity dmp = this . queryFactory . query ( DmpQuery . class ) . ids ( id ) . first ( ) ;
if ( dmp = = null ) {
throw new InvalidApplicationException ( " Dmp does not exist! " ) ;
}
2024-03-12 17:47:57 +01:00
List < DmpUserPersist > usersToAssign = new ArrayList < > ( ) ;
2024-02-22 12:57:42 +01:00
for ( DmpUserPersist user : users ) {
UUID userId = null ;
if ( user . getUser ( ) ! = null ) {
userId = user . getUser ( ) ;
} else if ( user . getEmail ( ) ! = null ) {
UserContactInfoEntity contactInfoEntity = this . queryFactory . query ( UserContactInfoQuery . class ) . values ( user . getEmail ( ) ) . types ( ContactInfoType . Email ) . first ( ) ;
if ( contactInfoEntity ! = null ) {
userId = contactInfoEntity . getUserId ( ) ;
}
}
if ( userId ! = null ) {
user . setUser ( userId ) ;
2024-03-12 17:47:57 +01:00
usersToAssign . add ( user ) ;
2024-03-01 17:50:46 +01:00
if ( this . userScope . getUserId ( ) ! = userId ) {
this . sendDmpInvitationExistingUser ( user . getUser ( ) , dmp , user . getRole ( ) ) ;
}
2024-02-22 12:57:42 +01:00
} else if ( user . getEmail ( ) ! = null ) {
this . sendDmpInvitationExternalUser ( user . getEmail ( ) , dmp , user . getRole ( ) ) ;
2023-12-14 13:02:30 +01:00
}
}
2024-03-21 17:44:19 +01:00
if ( ! usersToAssign . isEmpty ( ) & & persistUsers ) this . assignUsers ( id , usersToAssign , null , true ) ;
return usersToAssign ;
2023-12-14 13:02:30 +01:00
}
2023-12-15 10:51:08 +01:00
private void sendDmpInvitationExistingUser ( UUID userId , DmpEntity dmp , DmpUserRole role ) throws InvalidApplicationException {
UserEntity recipient = this . queryFactory . query ( UserQuery . class ) . ids ( userId ) . isActive ( IsActive . Active ) . first ( ) ;
String email = this . queryFactory . query ( UserContactInfoQuery . class ) . userIds ( recipient . getId ( ) ) . first ( ) . getValue ( ) ;
2024-01-10 16:46:45 +01:00
this . createDmpInvitationExistingUserEvent ( recipient , dmp , role , email , NotificationContactType . EMAIL ) ;
this . createDmpInvitationExistingUserEvent ( recipient , dmp , role , email , NotificationContactType . IN_APP ) ;
}
private void createDmpInvitationExistingUserEvent ( UserEntity recipient , DmpEntity dmp , DmpUserRole role , String email , NotificationContactType type ) throws InvalidApplicationException {
2023-12-14 13:02:30 +01:00
2024-01-19 14:12:33 +01:00
NotifyIntegrationEvent event = new NotifyIntegrationEvent ( ) ;
2023-12-14 13:02:30 +01:00
event . setUserId ( this . userScope . getUserIdSafe ( ) ) ;
List < ContactPair > contactPairs = new ArrayList < > ( ) ;
contactPairs . add ( new ContactPair ( ContactInfoType . Email , email ) ) ;
NotificationContactData contactData = new NotificationContactData ( contactPairs , null , null ) ;
event . setContactHint ( jsonHandlingService . toJsonSafe ( contactData ) ) ;
2024-01-10 16:46:45 +01:00
event . setContactTypeHint ( type ) ;
2024-01-04 15:25:07 +01:00
event . setNotificationType ( notificationProperties . getDmpInvitationExistingUserType ( ) ) ;
2023-12-15 10:51:08 +01:00
NotificationFieldData data = new NotificationFieldData ( ) ;
List < FieldInfo > fieldInfoList = new ArrayList < > ( ) ;
fieldInfoList . add ( new FieldInfo ( " {recipient} " , DataType . String , recipient . getName ( ) ) ) ;
fieldInfoList . add ( new FieldInfo ( " {reasonName} " , DataType . String , this . queryFactory . query ( UserQuery . class ) . ids ( this . userScope . getUserIdSafe ( ) ) . first ( ) . getName ( ) ) ) ;
fieldInfoList . add ( new FieldInfo ( " {dmpname} " , DataType . String , dmp . getLabel ( ) ) ) ;
fieldInfoList . add ( new FieldInfo ( " {dmprole} " , DataType . String , role . toString ( ) ) ) ;
2023-12-15 15:06:30 +01:00
fieldInfoList . add ( new FieldInfo ( " {id} " , DataType . String , dmp . getId ( ) . toString ( ) ) ) ;
2023-12-15 10:51:08 +01:00
data . setFields ( fieldInfoList ) ;
event . setData ( jsonHandlingService . toJsonSafe ( data ) ) ;
eventHandler . handle ( event ) ;
}
private void sendDmpInvitationExternalUser ( String email , DmpEntity dmp , DmpUserRole role ) throws JAXBException , InvalidApplicationException {
String token = this . createActionConfirmation ( email , dmp , role ) ;
2024-01-19 14:12:33 +01:00
NotifyIntegrationEvent event = new NotifyIntegrationEvent ( ) ;
2023-12-15 10:51:08 +01:00
event . setUserId ( this . userScope . getUserIdSafe ( ) ) ;
List < ContactPair > contactPairs = new ArrayList < > ( ) ;
contactPairs . add ( new ContactPair ( ContactInfoType . Email , email ) ) ;
NotificationContactData contactData = new NotificationContactData ( contactPairs , null , null ) ;
event . setContactHint ( jsonHandlingService . toJsonSafe ( contactData ) ) ;
event . setContactTypeHint ( NotificationContactType . EMAIL ) ;
2024-01-04 15:25:07 +01:00
event . setNotificationType ( notificationProperties . getDmpInvitationExternalUserType ( ) ) ;
2023-12-14 13:02:30 +01:00
NotificationFieldData data = new NotificationFieldData ( ) ;
List < FieldInfo > fieldInfoList = new ArrayList < > ( ) ;
fieldInfoList . add ( new FieldInfo ( " {recipient} " , DataType . String , email ) ) ;
2023-12-15 10:51:08 +01:00
fieldInfoList . add ( new FieldInfo ( " {confirmationToken} " , DataType . String , token ) ) ;
2023-12-14 13:02:30 +01:00
fieldInfoList . add ( new FieldInfo ( " {dmpname} " , DataType . String , dmp . getLabel ( ) ) ) ;
fieldInfoList . add ( new FieldInfo ( " {dmprole} " , DataType . String , role . toString ( ) ) ) ;
data . setFields ( fieldInfoList ) ;
event . setData ( jsonHandlingService . toJsonSafe ( data ) ) ;
eventHandler . handle ( event ) ;
}
2023-12-15 10:51:08 +01:00
private String createActionConfirmation ( String email , DmpEntity dmp , DmpUserRole role ) throws JAXBException , InvalidApplicationException {
ActionConfirmationPersist persist = new ActionConfirmationPersist ( ) ;
persist . setType ( ActionConfirmationType . DmpInvitation ) ;
persist . setStatus ( ActionConfirmationStatus . Requested ) ;
persist . setToken ( UUID . randomUUID ( ) . toString ( ) ) ;
persist . setDmpInvitation ( new DmpInvitationPersist ( email , dmp . getId ( ) , role ) ) ;
2024-01-04 15:25:07 +01:00
persist . setExpiresAt ( Instant . now ( ) . plusSeconds ( this . notificationProperties . getEmailExpirationTimeSeconds ( ) ) ) ;
2023-12-21 17:45:49 +01:00
validatorFactory . validator ( ActionConfirmationPersist . ActionConfirmationPersistValidator . class ) . validateForce ( persist ) ;
2023-12-15 10:51:08 +01:00
this . actionConfirmationService . persist ( persist , null ) ;
return persist . getToken ( ) ;
}
2023-12-14 13:02:30 +01:00
2024-03-21 11:12:12 +01:00
public void dmpInvitationAccept ( String token ) {
2023-12-14 17:19:43 +01:00
ActionConfirmationEntity action = this . queryFactory . query ( ActionConfirmationQuery . class ) . tokens ( token ) . types ( ActionConfirmationType . DmpInvitation ) . isActive ( IsActive . Active ) . first ( ) ;
2023-12-14 13:02:30 +01:00
if ( action = = null ) {
2023-12-15 09:15:00 +01:00
throw new MyApplicationException ( " Token does not exist! " ) ;
2023-12-14 13:02:30 +01:00
}
if ( action . getStatus ( ) . equals ( ActionConfirmationStatus . Accepted ) ) {
2023-12-15 09:15:00 +01:00
throw new MyApplicationException ( " Invitation is already confirmed! " ) ;
2023-12-14 13:02:30 +01:00
}
if ( action . getExpiresAt ( ) . compareTo ( Instant . now ( ) ) < 0 ) {
2023-12-15 09:15:00 +01:00
throw new MyApplicationException ( " Token has expired! " ) ;
2023-12-14 13:02:30 +01:00
}
DmpInvitationEntity dmpInvitation = this . xmlHandlingService . fromXmlSafe ( DmpInvitationEntity . class , action . getData ( ) ) ;
2024-03-12 17:47:57 +01:00
DmpUserEntity data = new DmpUserEntity ( ) ;
data . setId ( UUID . randomUUID ( ) ) ;
data . setIsActive ( IsActive . Active ) ;
data . setCreatedAt ( Instant . now ( ) ) ;
data . setUpdatedAt ( Instant . now ( ) ) ;
data . setRole ( dmpInvitation . getRole ( ) ) ;
data . setUserId ( this . userScope . getUserIdSafe ( ) ) ;
data . setDmpId ( dmpInvitation . getDmpId ( ) ) ;
this . entityManager . persist ( data ) ;
2023-12-14 13:02:30 +01:00
action . setStatus ( ActionConfirmationStatus . Accepted ) ;
this . entityManager . merge ( action ) ;
}
2023-10-23 10:31:07 +02:00
}