@RequestMapping("/admin/updateType")
 @ResponseBody
 public String updateType(
     HttpSession session,
     String mm_manager_id,
     String mm_manager_is_use,
     String mm_manager_nickname) {
   try {
     Admin manager = (Admin) session.getAttribute(ACCOUNT_KEY);
     Object[] params = new Object[] {mm_manager_id, mm_manager_is_use};
     // mm_manager_is_use :0 1 是禁止和启动管理员 2是删除管理员
     if ("2".equals(mm_manager_is_use)) {
       // 删除
       adminServiceDelete.delete(mm_manager_id);
     } else {
       // 更改管理员状态
       adminUpdateService.update(params);
     }
     // 日志记录
     switch (Integer.parseInt(mm_manager_is_use)) {
       case 0:
         logoService.save(new LogoObj("禁用管理员:" + mm_manager_nickname, manager.getMm_manager_id()));
         break;
       case 1:
         logoService.save(new LogoObj("启用管理员:" + mm_manager_nickname, manager.getMm_manager_id()));
         break;
       case 2:
         logoService.save(new LogoObj("删除管理员:" + mm_manager_nickname, manager.getMm_manager_id()));
         break;
     }
     return toJSONString(SUCCESS);
   } catch (ServiceException e) {
     return toJSONString(ERROR_1);
   }
 }
      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);
        }
      }
  @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;
  }