Skip to content

Commit 94282b8

Browse files
authored
PRT-913: Fix info panels when move document into sharedNotebooks (#327)
1 parent 853d500 commit 94282b8

File tree

11 files changed

+290
-77
lines changed

11 files changed

+290
-77
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3009,7 +3009,7 @@
30093009
<jstl.version>1.1.2</jstl.version>
30103010
<lucene.version>5.5.5</lucene.version>
30113011
<netty.version>4.1.63.Final</netty.version>
3012-
<rspace-core-model.version>2.9.0</rspace-core-model.version>
3012+
<rspace-core-model.version>2.10.0</rspace-core-model.version>
30133013
<servlet.version>3.1.0</servlet.version>
30143014
<sitemesh.version>2.4.2</sitemesh.version>
30153015
<urlrewrite.version>4.0.3</urlrewrite.version>

src/main/java/com/researchspace/model/dtos/ShareConfigElement.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,29 @@ public class ShareConfigElement {
1919
private Long externalGroupId;
2020

2121
private String operation;
22-
private List<String> allowedOps = Arrays.asList(new String[] {"read", "write"});
22+
private List<String> allowedOps = Arrays.asList("read", "write");
2323

2424
private boolean isAutoshare = false;
2525
private String publicationSummary;
2626
private boolean displayContactDetails;
2727
private boolean publishOnInternet;
2828

2929
/**
30-
* Assumes 'id' is a group Id. Set UserId explicitly if the object identified by id is a user, not
31-
* a group.
30+
* Assumes 'groupId' is a group Id. Set UserId explicitly if the object identified by id is a
31+
* user, not a group.
3232
*
33-
* @param id
33+
* @param groupId
3434
* @param operation
3535
*/
36-
public ShareConfigElement(Long id, String operation) {
37-
this.groupid = id;
36+
public ShareConfigElement(Long groupId, String operation) {
37+
this.groupid = groupId;
3838
this.operation = operation;
3939
}
4040

4141
/**
42-
* ALternate constructor that will set user or group id properly depending on the
42+
* Alternate constructor that will set user or group id properly depending on the
4343
*
44-
* @param id
44+
* @param rgs
4545
* @param operation
4646
*/
4747
public ShareConfigElement(RecordGroupSharing rgs, String operation) {

src/main/java/com/researchspace/service/GroupManager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ Group addMembersToProjectGroup(
7777
*/
7878
Group removeGroup(Long groupId, User subject);
7979

80+
/**
81+
* Returns the group from shareFolder (or any of the subfolders fo the share folder)
82+
*
83+
* @param user
84+
* @param sharedFolder
85+
* @return Returns the group
86+
*/
87+
Group getGroupFromAnyLevelOfSharedFolder(User user, Folder sharedFolder);
88+
8089
/**
8190
* Changes the role in a group for the specified user
8291
*

src/main/java/com/researchspace/service/SharingHandler.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
import com.researchspace.model.Group;
44
import com.researchspace.model.RecordGroupSharing;
55
import com.researchspace.model.User;
6+
import com.researchspace.model.dto.SharingResult;
67
import com.researchspace.model.dtos.ShareConfigCommand;
8+
import com.researchspace.model.record.BaseRecord;
79
import com.researchspace.model.record.Folder;
10+
import com.researchspace.model.record.Notebook;
811
import com.researchspace.model.views.ServiceOperationResult;
912
import com.researchspace.model.views.ServiceOperationResultCollection;
1013

@@ -14,9 +17,14 @@ public interface SharingHandler {
1417
ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> shareRecords(
1518
ShareConfigCommand shareConfig, User subject);
1619

20+
SharingResult shareRecordsWithResult(ShareConfigCommand shareConfig, User sharer);
21+
1722
ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> shareIntoSharedFolder(
1823
User user, Folder sharedFolder, Long recordId);
1924

25+
SharingResult moveIntoSharedNotebook(
26+
Group group, BaseRecord baseRecordToMove, Notebook targetSharedNotebook);
27+
2028
ServiceOperationResult<RecordGroupSharing> unshare(Long recordGroupShareId, User subject);
2129

2230
/**

src/main/java/com/researchspace/service/impl/GroupManagerImpl.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.researchspace.service.impl;
22

3+
import static com.researchspace.service.RecordDeletionManager.MIN_PATH_LENGTH_TOSHARED_ROOT_FOLDER;
34
import static com.researchspace.service.UserFolderCreator.SHARED_SNIPPETS_FOLDER_PREFIX;
45

56
import com.researchspace.Constants;
@@ -55,6 +56,7 @@
5556
import com.researchspace.model.record.Folder;
5657
import com.researchspace.model.record.IRecordFactory;
5758
import com.researchspace.model.record.IllegalAddChildOperation;
59+
import com.researchspace.model.record.RSPath;
5860
import com.researchspace.model.record.RecordToFolder;
5961
import com.researchspace.model.views.GroupInvitation;
6062
import com.researchspace.model.views.GroupInvitation.Invitee;
@@ -766,6 +768,20 @@ public Group removeGroup(Long groupId, User subject) {
766768
return group;
767769
}
768770

771+
public Group getGroupFromAnyLevelOfSharedFolder(User user, Folder sharedFolder) {
772+
Optional<Folder> sharedFolderRoot =
773+
folderMgr.getGroupOrIndividualShrdFolderRootFromSharedSubfolder(sharedFolder.getId(), user);
774+
RSPath path = folderMgr.getShortestPathToSharedRootFolder(sharedFolder.getId(), user);
775+
if (path.isEmpty() || path.size() <= MIN_PATH_LENGTH_TOSHARED_ROOT_FOLDER) {
776+
String msg =
777+
String.format(
778+
"The folder '%s' is not a shared subfolder - id [%d] is not in a shared folder!",
779+
sharedFolder.getName(), sharedFolder.getId());
780+
throw new IllegalArgumentException(msg);
781+
}
782+
return this.getGroupByCommunalGroupFolderId(sharedFolderRoot.get().getId());
783+
}
784+
769785
@Override
770786
public List<GroupInvitation> getPendingGroupInvitationsByGroupId(Long groupId) {
771787
List<GroupMessageOrRequest> groupMsges = communicationDao.getGroupMessageByGroupId(groupId);

src/main/java/com/researchspace/service/impl/SharingHandlerImpl.java

Lines changed: 89 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.researchspace.service.impl;
22

3-
import static com.researchspace.service.RecordDeletionManager.MIN_PATH_LENGTH_TOSHARED_ROOT_FOLDER;
4-
53
import com.researchspace.model.AbstractUserOrGroupImpl;
64
import com.researchspace.model.Group;
75
import com.researchspace.model.RecordGroupSharing;
@@ -10,14 +8,18 @@
108
import com.researchspace.model.audittrail.AuditTrailService;
119
import com.researchspace.model.audittrail.GenericEvent;
1210
import com.researchspace.model.audittrail.ShareRecordAuditEvent;
11+
import com.researchspace.model.dto.SharingResult;
1312
import com.researchspace.model.dtos.ShareConfigCommand;
1413
import com.researchspace.model.dtos.ShareConfigElement;
14+
import com.researchspace.model.field.ErrorList;
1515
import com.researchspace.model.permissions.ConstraintBasedPermission;
1616
import com.researchspace.model.permissions.IPermissionUtils;
1717
import com.researchspace.model.permissions.IdConstraint;
1818
import com.researchspace.model.permissions.PermissionDomain;
19+
import com.researchspace.model.record.BaseRecord;
1920
import com.researchspace.model.record.Folder;
2021
import com.researchspace.model.record.IllegalAddChildOperation;
22+
import com.researchspace.model.record.Notebook;
2123
import com.researchspace.model.record.RSPath;
2224
import com.researchspace.model.views.ServiceOperationResult;
2325
import com.researchspace.model.views.ServiceOperationResultCollection;
@@ -28,10 +30,14 @@
2830
import com.researchspace.service.UserManager;
2931
import java.util.Arrays;
3032
import java.util.List;
31-
import java.util.Optional;
33+
import java.util.Objects;
34+
import java.util.stream.Collectors;
3235
import lombok.extern.slf4j.Slf4j;
36+
import org.apache.commons.lang3.Validate;
3337
import org.apache.shiro.authz.AuthorizationException;
38+
import org.jetbrains.annotations.NotNull;
3439
import org.springframework.beans.factory.annotation.Autowired;
40+
import org.springframework.transaction.annotation.Transactional;
3541

3642
@Slf4j
3743
public class SharingHandlerImpl implements SharingHandler {
@@ -89,20 +95,7 @@ public ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing>
8995
@Override
9096
public ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing>
9197
shareIntoSharedFolder(User user, Folder sharedFolder, Long recordId) {
92-
Optional<Folder> sharedFolderRoot =
93-
folderManager.getGroupOrIndividualShrdFolderRootFromSharedSubfolder(
94-
sharedFolder.getId(), user);
95-
RSPath path = folderManager.getShortestPathToSharedRootFolder(sharedFolder.getId(), user);
96-
if (path.isEmpty() || path.size() <= MIN_PATH_LENGTH_TOSHARED_ROOT_FOLDER) {
97-
String msg =
98-
String.format(
99-
"The folder '%s' is not a shared subfolder - id [%d] is not in a shared folder!",
100-
sharedFolder.getName(), sharedFolder.getId());
101-
throw new IllegalArgumentException(msg);
102-
}
103-
104-
Group sharedGroup =
105-
groupManager.getGroupByCommunalGroupFolderId(sharedFolderRoot.get().getId());
98+
Group sharedGroup = groupManager.getGroupFromAnyLevelOfSharedFolder(user, sharedFolder);
10699
ShareConfigElement shareConfigElement = new ShareConfigElement(sharedGroup.getId(), "write");
107100
shareConfigElement.setGroupFolderId(sharedFolder.getId());
108101
ShareConfigCommand shareConfig =
@@ -162,4 +155,83 @@ private ServiceOperationResult<RecordGroupSharing> doUnshare(
162155

163156
return rc;
164157
}
158+
159+
@Override
160+
public SharingResult shareRecordsWithResult(ShareConfigCommand shareConfig, User sharer) {
161+
ErrorList error = new ErrorList();
162+
ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> result =
163+
this.shareRecords(shareConfig, sharer);
164+
result.getExceptions().forEach(e -> error.addErrorMsg(e.getMessage()));
165+
result.getFailures().forEach(rgs -> error.addErrorMsg(rgs.getShared().getName()));
166+
return new SharingResult(buildSharedIdList(result), buildPublicLinkList(result), error);
167+
}
168+
169+
@Override
170+
@Transactional
171+
public SharingResult moveIntoSharedNotebook(
172+
Group group, BaseRecord baseRecordToMove, Notebook targetSharedNotebook) {
173+
Validate.isTrue(
174+
targetSharedNotebook != null && targetSharedNotebook.isShared(),
175+
"Notebook must be already shared");
176+
177+
if (baseRecordToMove.isShared()) {
178+
RSPath pathToRootSharedFolder =
179+
folderManager.getShortestPathToSharedRootFolder(
180+
targetSharedNotebook.getId(), baseRecordToMove.getOwner());
181+
sharingManager.unshareFromSharedFolder(
182+
baseRecordToMove.getOwner(), baseRecordToMove, pathToRootSharedFolder);
183+
}
184+
ShareConfigCommand shareConfig =
185+
buildShareCommandForTarget(baseRecordToMove.getId(), group.getId(), targetSharedNotebook);
186+
SharingResult sharingResult = shareRecordsWithResult(shareConfig, baseRecordToMove.getOwner());
187+
if (sharingResult.getError().hasErrorMessages()) {
188+
throw new IllegalStateException(
189+
"Errors while moving into Shared Notebook: ["
190+
+ sharingResult.getError().getAllErrorMessagesAsStringsSeparatedBy(",")
191+
+ "]");
192+
}
193+
return sharingResult;
194+
}
195+
196+
@NotNull
197+
private static ShareConfigCommand buildShareCommandForTarget(
198+
Long idToMove, Long groupId, Folder target) {
199+
ShareConfigElement shareElement = new ShareConfigElement(groupId, "read");
200+
shareElement.setGroupFolderId(target.getId());
201+
return new ShareConfigCommand(
202+
new Long[] {idToMove}, new ShareConfigElement[] {shareElement}, false);
203+
}
204+
205+
@NotNull
206+
private static List<Long> buildSharedIdList(
207+
ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> result) {
208+
List<Long> sharedIds =
209+
result.getResults().stream()
210+
.map(rgs -> rgs.getShared().getId())
211+
.collect(Collectors.toList());
212+
return sharedIds;
213+
}
214+
215+
@NotNull
216+
private static List<String> buildPublicLinkList(
217+
ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> result) {
218+
List<String> publicLinks =
219+
result.getResults().stream()
220+
.map(
221+
rgs -> {
222+
if (rgs.getPublicLink() == null) {
223+
return null;
224+
}
225+
String prefix = "";
226+
if (rgs.getShared().isStructuredDocument()) {
227+
prefix = "/public/publishedView/document/";
228+
} else if (rgs.getShared().isNotebook()) {
229+
prefix = "/public/publishedView/notebook/";
230+
}
231+
return rgs.getShared().getName() + "_&_&_" + prefix + rgs.getPublicLink();
232+
})
233+
.filter(Objects::nonNull)
234+
.collect(Collectors.toList());
235+
return publicLinks;
236+
}
165237
}

src/main/java/com/researchspace/webapp/controller/WorkspaceController.java

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@
9090
import java.util.HashMap;
9191
import java.util.List;
9292
import java.util.Map;
93-
import java.util.Objects;
9493
import java.util.Optional;
9594
import java.util.Set;
9695
import java.util.function.BiConsumer;
@@ -597,20 +596,42 @@ public ModelAndView move(
597596
}
598597

599598
int moveCounter = 0;
600-
for (Long id : toMove) {
601-
if (target.getId().equals(id)) {
599+
for (Long recordIdToMove : toMove) {
600+
if (target.getId().equals(recordIdToMove)) {
602601
continue;
603602
}
604603
Folder sourceFolder =
605-
getMoveSourceFolderId(id, settings.getParentFolderId(), user, usersRootFolder);
606-
boolean isFolder = !isRecord(id);
604+
getMoveSourceFolderId(
605+
recordIdToMove, settings.getParentFolderId(), user, usersRootFolder);
606+
boolean isFolder = !isRecord(recordIdToMove) || recordManager.get(recordIdToMove).isFolder();
607607
ServiceOperationResult<? extends BaseRecord> moveResult = null;
608608
if (isFolder) {
609-
moveResult = folderManager.move(id, target.getId(), sourceFolder.getId(), user);
609+
moveResult = folderManager.move(recordIdToMove, target.getId(), sourceFolder.getId(), user);
610610
} else {
611-
moveResult = recordManager.move(id, target.getId(), sourceFolder.getId(), user);
611+
BaseRecord baseRecordToMove = recordManager.get(recordIdToMove);
612+
if (target.isNotebook() && target.isShared()) {
613+
try {
614+
Group group = groupManager.getGroupFromAnyLevelOfSharedFolder(user, sourceFolder);
615+
SharingResult sharingResult =
616+
recordShareHandler.moveIntoSharedNotebook(
617+
group, baseRecordToMove, (Notebook) target);
618+
if (!sharingResult.getSharedIds().isEmpty()) {
619+
moveCounter = moveCounter + sharingResult.getSharedIds().size();
620+
}
621+
} catch (Exception ex) {
622+
log.error(
623+
"It was not possible to move the record [{}] into the shared notebook [{}]: {}",
624+
baseRecordToMove.getId(),
625+
target.getId(),
626+
ex.getMessage());
627+
break;
628+
}
629+
} else {
630+
moveResult =
631+
recordManager.move(recordIdToMove, target.getId(), sourceFolder.getId(), user);
632+
}
612633
}
613-
if (moveResult.isSucceeded()) {
634+
if (moveResult != null && moveResult.isSucceeded()) {
614635
moveCounter++;
615636
auditService.notify(new MoveAuditEvent(user, moveResult.getEntity(), sourceFolder, target));
616637
}
@@ -760,32 +781,7 @@ public AjaxReturnObject<SharingResult> shareRecord(
760781
anonymousShare.setPublishOnInternet(existingAnonymousShareConfig.isPublishOnInternet());
761782
shareConfig.setValues(new ShareConfigElement[] {anonymousShare});
762783
}
763-
ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> result =
764-
recordShareHandler.shareRecords(shareConfig, sharer);
765-
List<Long> sharedIds =
766-
result.getResults().stream()
767-
.map(rgs -> rgs.getShared().getId())
768-
.collect(Collectors.toList());
769-
List<String> publicLinks =
770-
result.getResults().stream()
771-
.map(
772-
rgs -> {
773-
if (rgs.getPublicLink() == null) {
774-
return null;
775-
}
776-
String prefix = "";
777-
if (rgs.getShared().isStructuredDocument()) {
778-
prefix = "/public/publishedView/document/";
779-
} else if (rgs.getShared().isNotebook()) {
780-
prefix = "/public/publishedView/notebook/";
781-
}
782-
return rgs.getShared().getName() + "_&_&_" + prefix + rgs.getPublicLink();
783-
})
784-
.filter(Objects::nonNull)
785-
.collect(Collectors.toList());
786-
result.getExceptions().forEach(e -> error.addErrorMsg(e.getMessage()));
787-
result.getFailures().forEach(rgs -> error.addErrorMsg(rgs.getShared().getName()));
788-
SharingResult sharingResult = new SharingResult(sharedIds, publicLinks);
784+
SharingResult sharingResult = recordShareHandler.shareRecordsWithResult(shareConfig, sharer);
789785
return new AjaxReturnObject<>(sharingResult, error);
790786
}
791787

src/main/java/com/researchspace/webapp/controller/cloud/RSCommunityController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,8 @@ public AjaxReturnObject<SharingResult> shareRecord(
457457
}
458458
}
459459
}
460-
SharingResult sharingResult = new SharingResult(new ArrayList<>(sharedIds), new ArrayList<>());
460+
SharingResult sharingResult =
461+
new SharingResult(new ArrayList<>(sharedIds), new ArrayList<>(), error);
461462
return new AjaxReturnObject<>(sharingResult, error);
462463
}
463464

0 commit comments

Comments
 (0)