18
18
import org .slf4j .LoggerFactory ;
19
19
import org .springframework .beans .factory .annotation .Autowired ;
20
20
import org .springframework .context .annotation .Bean ;
21
+ import org .springframework .data .util .Pair ;
21
22
import org .springframework .messaging .Message ;
22
23
import org .springframework .stereotype .Service ;
23
24
import org .springframework .transaction .annotation .Transactional ;
@@ -160,7 +161,9 @@ private ElementAttributes insertElement(ElementAttributes elementAttributes, UUI
160
161
elementAttributes .getDescription (),
161
162
now ,
162
163
now ,
163
- elementAttributes .getOwner ()
164
+ elementAttributes .getOwner (),
165
+ false ,
166
+ null
164
167
)
165
168
)
166
169
);
@@ -257,7 +260,7 @@ private Stream<ElementAttributes> getDirectoryElementsStream(UUID directoryUuid,
257
260
}
258
261
259
262
private Stream <ElementAttributes > getAllDirectoryElementsStream (UUID directoryUuid , List <String > types , String userId ) {
260
- List <DirectoryElementEntity > directoryElements = directoryElementRepository .findAllByParentId (directoryUuid );
263
+ List <DirectoryElementEntity > directoryElements = directoryElementRepository .findAllByParentIdAndStashed (directoryUuid , false );
261
264
Map <UUID , Long > subdirectoriesCountsMap = getSubDirectoriesCountMap (userId , types , directoryElements );
262
265
return directoryElements
263
266
.stream ()
@@ -517,7 +520,7 @@ private Boolean isRootDirectoryExist(String rootName) {
517
520
}
518
521
519
522
private Boolean isElementExists (UUID parentDirectoryUuid , String elementName , String type ) {
520
- return !directoryElementRepository .findByNameAndParentIdAndType (elementName , parentDirectoryUuid , type ).isEmpty ();
523
+ return !directoryElementRepository .findByNameAndParentIdAndTypeAndStashed (elementName , parentDirectoryUuid , type , false ).isEmpty ();
521
524
}
522
525
523
526
public UUID getDirectoryUuid (String directoryName , UUID parentDirectoryUuid ) {
@@ -535,11 +538,11 @@ public UUID getDirectoryUuid(String directoryName, UUID parentDirectoryUuid) {
535
538
}
536
539
537
540
public boolean elementExists (UUID parentDirectoryUuid , String elementName , String type ) {
538
- return !directoryElementRepository .findByNameAndParentIdAndType (elementName , parentDirectoryUuid , type ).isEmpty ();
541
+ return !directoryElementRepository .findByNameAndParentIdAndTypeAndStashed (elementName , parentDirectoryUuid , type , false ).isEmpty ();
539
542
}
540
543
541
544
public List <ElementAttributes > getElements (List <UUID > ids , boolean strictMode , List <String > types ) {
542
- List <DirectoryElementEntity > elementEntities = directoryElementRepository .findAllById (ids );
545
+ List <DirectoryElementEntity > elementEntities = directoryElementRepository .findAllByIdInAndStashed (ids , false );
543
546
544
547
if (strictMode && elementEntities .size () != ids .stream ().distinct ().count ()) {
545
548
throw new DirectoryException (NOT_FOUND );
@@ -613,4 +616,172 @@ public String getDuplicateNameCandidate(UUID directoryUuid, String elementName,
613
616
}
614
617
return nameCandidate (elementName , i );
615
618
}
619
+
620
+ private List <DirectoryElementEntity > getEntitiesToRestore (List <DirectoryElementEntity > entities ,
621
+ List <DirectoryElementEntity > rejectedEntities ,
622
+ String userId ,
623
+ boolean isParentPrivate ) {
624
+ if (isParentPrivate ) {
625
+ return getEntitiesCreatedBySameUser (entities , rejectedEntities , userId );
626
+ }
627
+
628
+ return entities .stream ()
629
+ .filter (entity -> {
630
+ boolean isUpdatable = Objects .equals (userId , entity .getOwner ()) || !entity .getIsPrivate ();
631
+ if (!isUpdatable ) {
632
+ rejectedEntities .add (entity );
633
+ }
634
+ return isUpdatable ;
635
+ })
636
+ .toList ();
637
+ }
638
+
639
+ public void restoreElements (List <UUID > elementsUuid , UUID parentUuid , String userId ) {
640
+ // Get parent directory
641
+ ElementAttributes parent = getElement (parentUuid );
642
+
643
+ // Get all updatable entities. Entities should be public or created by the user, so it can be restored
644
+ List <DirectoryElementEntity > notUpdatableEntities = new ArrayList <>();
645
+ List <DirectoryElementEntity > allStashedElements = directoryElementRepository .findAllStashedElements (elementsUuid , true , userId );
646
+ List <DirectoryElementEntity > updatableEntities = getEntitiesToRestore (allStashedElements , notUpdatableEntities , userId , parent .getAccessRights ().isPrivate ());
647
+
648
+ List <DirectoryElementEntity > entities = updatableEntities
649
+ .stream ()
650
+ .flatMap (entity -> {
651
+ entity .setParentId (parentUuid );
652
+ entity .setName (getDuplicateNameCandidate (parentUuid , entity .getName (), entity .getType (), userId ));
653
+
654
+ // Retrieve descendants of the current entity
655
+ List <DirectoryElementEntity > descendants = getEntitiesToRestore (
656
+ directoryElementRepository .findAllDescendantsWithSameStashDate (entity .getId (), userId ),
657
+ notUpdatableEntities ,
658
+ userId ,
659
+ parent .getAccessRights ().isPrivate ());
660
+
661
+ // Combine parent and descendants into a single list
662
+ List <DirectoryElementEntity > result = new ArrayList <>();
663
+ result .add (entity );
664
+ result .addAll (descendants );
665
+
666
+ return result .stream ().map (e -> e .stashElement (false , null ));
667
+ })
668
+ .toList ();
669
+
670
+ directoryElementRepository .saveAll (entities );
671
+ notificationService .emitDirectoryChanged (
672
+ parentUuid ,
673
+ parent .getElementName (),
674
+ userId ,
675
+ null ,
676
+ parent .getAccessRights ().isPrivate (),
677
+ parentUuid == null ,
678
+ NotificationType .UPDATE_DIRECTORY
679
+ );
680
+ emitDirectoryChangedNotification (parentUuid , userId );
681
+ if (!notUpdatableEntities .isEmpty ()) {
682
+ throw new DirectoryException (NOT_ALLOWED );
683
+ }
684
+ }
685
+
686
+ public void stashElements (List <UUID > elementsUuid , String userId ) {
687
+ // we add the same stash date to all the elements that are deleted together
688
+ LocalDateTime stashDate = LocalDateTime .now ();
689
+ List <DirectoryElementEntity > entities = directoryElementRepository .findAllByIdInAndStashed (elementsUuid , false );
690
+ List <DirectoryElementEntity > notUpdatableEntities = new ArrayList <>();
691
+ List <DirectoryElementEntity > updatableEntities = getEntitiesCreatedBySameUser (entities , notUpdatableEntities , userId );
692
+
693
+ directoryElementRepository .saveAll (updatableEntities .stream ()
694
+ .flatMap (entity -> {
695
+ List <DirectoryElementEntity > descendants = directoryElementRepository .findAllDescendants (entity .getId (), userId );
696
+ // Combine parent and descendants into a single list
697
+ List <DirectoryElementEntity > result = new ArrayList <>();
698
+ result .add (entity );
699
+ result .addAll (descendants );
700
+ return result .stream ().map (e -> {
701
+ DirectoryElementEntity stashedElement = e .stashElement (true , stashDate );
702
+ if (Objects .equals (e .getType (), STUDY )) {
703
+ notificationService .emitDeletedStudy (entity .getId (), userId );
704
+ }
705
+ return stashedElement ;
706
+ });
707
+ })
708
+ .toList ());
709
+
710
+ updatableEntities .forEach (entity -> {
711
+ UUID parentUuid = getParentUuid (entity .getId ());
712
+ notificationService .emitDirectoryChanged (
713
+ parentUuid == null ? entity .getId () : parentUuid ,
714
+ entity .getName (),
715
+ userId ,
716
+ null ,
717
+ entity .getIsPrivate (),
718
+ parentUuid == null ,
719
+ parentUuid == null ? NotificationType .DELETE_DIRECTORY : NotificationType .UPDATE_DIRECTORY
720
+ );
721
+ });
722
+
723
+ if (!notUpdatableEntities .isEmpty ()) {
724
+ throw new DirectoryException (NOT_ALLOWED ,
725
+ String .format ("Some or all of the elements can not be deleted : %s" ,
726
+ String .join (", " , notUpdatableEntities .stream ().map (DirectoryElementEntity ::getName ).toList ())));
727
+ }
728
+ }
729
+
730
+ public List <Pair <ElementAttributes , Long >> getStashedElements (String userId ) {
731
+ List <DirectoryElementEntity > entities = directoryElementRepository .getElementsStashed (userId );
732
+ return entities .stream ()
733
+ .map (entity -> Pair .of (toElementAttributes (entity ), directoryElementRepository .countDescendants (entity .getId (), userId ) - 1 ))
734
+ .toList ();
735
+ }
736
+
737
+ public void deleteElements (List <UUID > elementsUuid , String userId ) {
738
+ // Get all updatable entities
739
+ List <DirectoryElementEntity > notUpdatableEntities = new ArrayList <>();
740
+ List <DirectoryElementEntity > updatableEntities = getEntitiesCreatedBySameUser (directoryElementRepository .findAllByIdInAndStashed (elementsUuid , true ), notUpdatableEntities , userId );
741
+
742
+ // Collect all entities with their descendents in one list
743
+ List <DirectoryElementEntity > allEntities = updatableEntities .stream ()
744
+ .flatMap (entity -> Stream .concat (directoryElementRepository .findAllDescendantsWithSameStashDate (entity .getId (), userId ).stream (),
745
+ Stream .of (entity )))
746
+ .toList ();
747
+
748
+ // Delete all entities
749
+ directoryElementRepository .deleteAllById (allEntities .stream ().map (DirectoryElementEntity ::getId ).toList ());
750
+
751
+ // Send notification for all deleted elements
752
+ allEntities .forEach (entity -> {
753
+ UUID parentUuid = entity .getParentId ();
754
+ notificationService .emitDirectoryChanged (
755
+ parentUuid == null ? entity .getId () : parentUuid ,
756
+ entity .getName (),
757
+ userId ,
758
+ null ,
759
+ entity .getIsPrivate (),
760
+ parentUuid == null ,
761
+ parentUuid == null ? NotificationType .DELETE_DIRECTORY : NotificationType .UPDATE_DIRECTORY
762
+ );
763
+ if (STUDY .equals (entity .getType ())) {
764
+ notificationService .emitDeletedStudy (entity .getId (), userId );
765
+ }
766
+ });
767
+ if (!notUpdatableEntities .isEmpty ()) {
768
+ throw new DirectoryException (NOT_ALLOWED ,
769
+ String .format ("Some or all of the elements can not be deleted : %s" ,
770
+ String .join (", " , notUpdatableEntities .stream ().map (DirectoryElementEntity ::getName ).toList ())));
771
+ }
772
+ }
773
+
774
+ private List <DirectoryElementEntity > getEntitiesCreatedBySameUser (List <DirectoryElementEntity > entities ,
775
+ List <DirectoryElementEntity > notUpdatableEntities ,
776
+ String userId ) {
777
+ return entities .stream ()
778
+ .filter (entity -> {
779
+ boolean isUpdatable = Objects .equals (userId , entity .getOwner ());
780
+ if (!isUpdatable ) {
781
+ notUpdatableEntities .add (entity );
782
+ }
783
+ return isUpdatable ;
784
+ })
785
+ .toList ();
786
+ }
616
787
}
0 commit comments