|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
package org.gcube.data.access.storagehub.handlers;
|
|
|
|
|
|
|
|
|
|
import java.util.Calendar;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.HashSet;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Set;
|
|
|
|
@ -38,6 +39,7 @@ import org.gcube.data.access.storagehub.accounting.AccountingHandler;
|
|
|
|
|
import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter;
|
|
|
|
|
import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter;
|
|
|
|
|
import org.gcube.data.access.storagehub.handlers.plugins.FolderPluginHandler;
|
|
|
|
|
import org.gcube.data.access.storagehub.types.ContentPair;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
|
@ -53,10 +55,10 @@ public class TrashHandler {
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
AuthorizationChecker authChecker;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
AccountingHandler accountingHandler;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
Item2NodeConverter item2Node;
|
|
|
|
|
|
|
|
|
@ -65,9 +67,9 @@ public class TrashHandler {
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
PathUtil pathUtil;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Inject FolderPluginHandler managerHandler;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
FolderPluginHandler folderHandler;
|
|
|
|
|
|
|
|
|
@ -84,21 +86,52 @@ public class TrashHandler {
|
|
|
|
|
removeNodesInternally(ses, item, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void retrieveContentsToDelete(Set<AbstractFileItem> itemsToDelete, Item itemToDelete) throws Exception{
|
|
|
|
|
|
|
|
|
|
private void retrieveItemsToDelete(Set<AbstractFileItem> itemsToDelete, Item itemToDelete) throws Exception{
|
|
|
|
|
if (itemToDelete instanceof AbstractFileItem) {
|
|
|
|
|
itemsToDelete.add(((AbstractFileItem) itemToDelete));
|
|
|
|
|
}else if (itemToDelete instanceof FolderItem) {
|
|
|
|
|
//only to be sure to not delete shared content
|
|
|
|
|
if (itemToDelete.isShared()) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<Item> items = Utils.getItemList((Node) itemToDelete.getRelatedNode(), Excludes.GET_ONLY_CONTENT , null, true, null);
|
|
|
|
|
for (Item item: items)
|
|
|
|
|
retrieveContentsToDelete(itemsToDelete, item);
|
|
|
|
|
retrieveItemsToDelete(itemsToDelete, item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Set<ContentPair> retrieveContentToDelete(Collection<AbstractFileItem> itemsToDelete) {
|
|
|
|
|
Set<ContentPair> contentSet = new HashSet<ContentPair>();
|
|
|
|
|
for (AbstractFileItem item: itemsToDelete) {
|
|
|
|
|
if (item.getContent()== null || item.getContent().getStorageId()==null) {
|
|
|
|
|
log.warn("item with id {} contains null content",item.getId());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
FolderManager manager = folderHandler.getFolderManager(item);
|
|
|
|
|
contentSet.add(new ContentPair(item.getContent(), manager.getStorageBackend()));
|
|
|
|
|
|
|
|
|
|
List<Version> versions = versionHandler.getContentVersionHistory((Node)item.getRelatedNode());
|
|
|
|
|
|
|
|
|
|
for (Version version: versions) {
|
|
|
|
|
try {
|
|
|
|
|
Content content = node2Item.getContent(version);
|
|
|
|
|
if (content!= null && content.getStorageId()!=null)
|
|
|
|
|
contentSet.add(new ContentPair(content, manager.getStorageBackend()));
|
|
|
|
|
}catch (Throwable t) {
|
|
|
|
|
log.warn("error retrieving version {}",version.getName(),t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}catch (Exception e) {
|
|
|
|
|
log.warn("item with id {} cannot be deleted",item.getId(),e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return contentSet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void removeNodesInternally(Session ses, Item itemToDelete, boolean onlyContent) throws RepositoryException, StorageHubException {
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
@ -108,32 +141,27 @@ public class TrashHandler {
|
|
|
|
|
if (itemToDelete instanceof TrashItem) {
|
|
|
|
|
List<Item> trashChildren = Utils.getItemList(nodeToDelete, Excludes.GET_ONLY_CONTENT, null, true, null);
|
|
|
|
|
for (Item itemContentToRetrieve: trashChildren)
|
|
|
|
|
retrieveContentsToDelete(itemsToDelete, itemContentToRetrieve);
|
|
|
|
|
retrieveItemsToDelete(itemsToDelete, itemContentToRetrieve);
|
|
|
|
|
} else
|
|
|
|
|
retrieveContentsToDelete(itemsToDelete, itemToDelete);
|
|
|
|
|
|
|
|
|
|
retrieveItemsToDelete(itemsToDelete, itemToDelete);
|
|
|
|
|
|
|
|
|
|
if (!onlyContent)
|
|
|
|
|
nodeToDelete.remove();
|
|
|
|
|
|
|
|
|
|
String ids = itemsToDelete.stream().map((i) -> i.getId()).collect(Collectors.joining(","));
|
|
|
|
|
log.debug("content ids to remove are {}",ids);
|
|
|
|
|
|
|
|
|
|
Set<ContentPair> contentToDelete = retrieveContentToDelete(itemsToDelete);
|
|
|
|
|
|
|
|
|
|
Runnable deleteFromStorageRunnable = AuthorizedTasks.bind(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
for (AbstractFileItem item: itemsToDelete ) {
|
|
|
|
|
for (ContentPair cp: contentToDelete ) {
|
|
|
|
|
try {
|
|
|
|
|
FolderManager manager = folderHandler.getFolderManager(item);
|
|
|
|
|
manager.getStorageBackend().onDelete(item.getContent());
|
|
|
|
|
List<Version> versions = versionHandler.getContentVersionHistory((Node)item.getRelatedNode());
|
|
|
|
|
|
|
|
|
|
for (Version version: versions) {
|
|
|
|
|
Content content = node2Item.getContent(version);
|
|
|
|
|
manager.getStorageBackend().onDelete(content);
|
|
|
|
|
}
|
|
|
|
|
log.debug("file with id {} correctly removed from storage {}",item.getId(), manager.getClass().getSimpleName());
|
|
|
|
|
cp.getStorageBackend().onDelete(cp.getContent());
|
|
|
|
|
log.debug("file with id {} correctly removed from storage {}",cp.getContent().getStorageId(),cp.getStorageBackend().getClass().getSimpleName());
|
|
|
|
|
}catch(Throwable t) {
|
|
|
|
|
log.warn("error removing file with id {} from storage",item.getId(), t);
|
|
|
|
|
log.warn("error removing file with id {} from storage {}",cp.getContent().getStorageId(), cp.getStorageBackend().getClass().getSimpleName(), t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -148,13 +176,13 @@ public class TrashHandler {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void moveToTrash(Session ses, Node nodeToDelete, Item item, String login) throws RepositoryException, BackendGenericError{
|
|
|
|
|
log.debug("moving node {} to trash ",item.getId());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final Node trashFolder = ses.getNode(pathUtil.getTrashPath(login, ses).toPath());
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ses.getWorkspace().getLockManager().lock(trashFolder.getPath(), true, true, 0,login);
|
|
|
|
|
ses.getWorkspace().getLockManager().lock(nodeToDelete.getPath(), true, true, 0,login);
|
|
|
|
|
|
|
|
|
@ -250,12 +278,12 @@ public class TrashHandler {
|
|
|
|
|
|
|
|
|
|
if (!node2Item.checkNodeType(node, FolderItem.class))
|
|
|
|
|
throw new InvalidCallParameters("destination Node is not a folder");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
destinationNode = node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
authChecker.checkWriteAuthorizationControl(ses, login, destinationNode.getIdentifier(), true );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ses.getWorkspace().getLockManager().lock(destinationNode.getPath(), true, true, 0,login);
|
|
|
|
|
String newNodePath = null;
|
|
|
|
|
try {
|
|
|
|
|