示例#1
0
  /** 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;
  }