/** See CMIS 1.0 section 2.2.4.15 deleteTree */ public FailedToDeleteDataImpl deleteTree() { FailedToDeleteDataImpl result = new FailedToDeleteDataImpl(); String id = getId(); try { Node node = getNode(); if (hasCheckOuts(node)) { result.setIds(Collections.<String>singletonList(id)); } else { Session session = node.getSession(); node.remove(); session.save(); result.setIds(Collections.<String>emptyList()); } } catch (RepositoryException e) { result.setIds(Collections.singletonList(id)); } return result; }
@Override public FailedToDeleteData deleteTree( CallContext callContext, String repositoryId, String folderId, Boolean allVersions, UnfileObject unfileObjects, Boolean continueOnFailure, ExtensionsData extension) { // ////////////////// // Inner classes // ////////////////// class DeleteTask implements Callable<Boolean> { private CallContext callContext; private String repositoryId; private Content content; private Boolean allVersions; public DeleteTask() {} public DeleteTask( CallContext callContext, String repositoryId, Content content, Boolean allVersions) { this.callContext = callContext; this.repositoryId = repositoryId; this.content = content; this.allVersions = allVersions; } @Override public Boolean call() throws Exception { try { objectServiceInternal.deleteObjectInternal( callContext, repositoryId, content, allVersions, true); return false; } catch (Exception e) { return true; } } } class WrappedExecutorService { private ExecutorService service; private Folder folder; private WrappedExecutorService() {}; public WrappedExecutorService(ExecutorService service, Folder folder) { this.service = service; this.folder = folder; } public ExecutorService getService() { return service; } public Folder getFolder() { return folder; } } class DeleteService { private Map<String, Future<Boolean>> failureIds; private WrappedExecutorService parentService; private CallContext callContext; private String repositoryId; private Content content; private Boolean allVersions; public DeleteService() {} public DeleteService( Map<String, Future<Boolean>> failureIds, WrappedExecutorService parentService, CallContext callContext, String repositoryId, Content content, Boolean allVersions) { super(); this.failureIds = failureIds; this.parentService = parentService; this.callContext = callContext; this.repositoryId = repositoryId; this.content = content; this.allVersions = allVersions; } public void execute() { if (content.isDocument()) { Future<Boolean> result = parentService .getService() .submit(new DeleteTask(callContext, repositoryId, content, allVersions)); failureIds.put(content.getId(), result); } else if (content.isFolder()) { WrappedExecutorService childrenService = new WrappedExecutorService(Executors.newFixedThreadPool(threadMax), (Folder) content); List<Content> children = contentService.getChildren(repositoryId, content.getId()); if (CollectionUtils.isNotEmpty(children)) { for (Content child : children) { DeleteService deleteService = new DeleteService( this.failureIds, childrenService, callContext, repositoryId, child, allVersions); deleteService.execute(); } } // wait til newService ends childrenService.getService().shutdown(); try { childrenService.getService().awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); } catch (InterruptedException e) { log.error(e, e); } // Lastly, delete self Future<Boolean> result = parentService .getService() .submit(new DeleteTask(callContext, repositoryId, content, allVersions)); failureIds.put(content.getId(), result); } } } // ////////////////// // General Exception // ////////////////// exceptionService.invalidArgumentRequiredString("objectId", folderId); Folder folder = contentService.getFolder(repositoryId, folderId); exceptionService.permissionDenied( callContext, repositoryId, PermissionMapping.CAN_DELETE_TREE_FOLDER, folder); exceptionService.constraintDeleteRootFolder(repositoryId, folderId); // ////////////////// // Specific Exception // ////////////////// if (folder == null) exceptionService.constraint(folderId, "deleteTree cannot be invoked on a non-folder object"); // ////////////////// // Body of the method // ////////////////// // Delete descendants Map<String, Future<Boolean>> failureIds = new HashMap<String, Future<Boolean>>(); DeleteService deleteService = new DeleteService( failureIds, new WrappedExecutorService(Executors.newFixedThreadPool(threadMax), folder), callContext, repositoryId, folder, allVersions); deleteService.execute(); solrUtil.callSolrIndexing(repositoryId); // Check FailedToDeleteData // FIXME Consider orphans that was failed to be deleted FailedToDeleteDataImpl fdd = new FailedToDeleteDataImpl(); List<String> ids = new ArrayList<String>(); for (Entry<String, Future<Boolean>> entry : failureIds.entrySet()) { Boolean failed; try { failed = entry.getValue().get(); if (failed) { ids.add(entry.getKey()); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } fdd.setIds(ids); return fdd; }