@Override
  public void handleException(Exception e) {
    _logger.error(e.getMessage(), e);

    if (!(e instanceof HttpResponseException)) {
      super.handleException(e);

      return;
    }

    HttpResponseException hre = (HttpResponseException) e;

    int statusCode = hre.getStatusCode();

    if (statusCode != HttpStatus.SC_NOT_FOUND) {
      super.handleException(e);

      return;
    }

    SyncAccount syncAccount = SyncAccountService.fetchSyncAccount(getSyncAccountId());

    if (syncAccount.getState() == SyncAccount.STATE_DISCONNECTED) {
      super.handleException(e);

      return;
    }

    SyncFile syncFile = (SyncFile) getParameterValue("syncFile");

    SyncFileService.deleteSyncFile(syncFile, false);
  }
  public static SyncFile moveFileSyncFile(
      Path filePath, long folderId, long syncAccountId, SyncFile syncFile) throws Exception {

    // Local sync file

    SyncFile targetSyncFile = fetchSyncFile(filePath.toString());

    if (targetSyncFile != null) {
      deleteSyncFile(targetSyncFile, false);
    }

    syncFile.setFilePathName(filePath.toString());
    syncFile.setParentFolderId(folderId);

    update(syncFile);

    // Remote sync file

    if ((syncFile.getState() != SyncFile.STATE_ERROR)
        && (syncFile.getState() != SyncFile.STATE_UNSYNCED)) {

      FileEventUtil.moveFile(folderId, syncAccountId, syncFile);
    }

    return syncFile;
  }
  protected void deleteFile(SyncWatchEvent syncWatchEvent) throws Exception {
    Path filePath = Paths.get(syncWatchEvent.getFilePathName());

    SyncFile syncFile = SyncFileService.fetchSyncFile(filePath.toString());

    if ((syncFile == null) || !FileUtil.notExists(Paths.get(syncFile.getFilePathName()))) {

      return;
    } else if ((syncFile.getState() == SyncFile.STATE_ERROR)
        || (syncFile.getState() == SyncFile.STATE_UNSYNCED)) {

      SyncFileService.deleteSyncFile(syncFile, false);

      return;
    } else if (syncFile.getState() == SyncFile.STATE_IN_PROGRESS) {
      Set<Event> events = FileEventManager.getEvents(syncFile.getSyncFileId());

      for (Event event : events) {
        event.cancel();
      }

      if (isPendingTypePK(syncFile)) {
        SyncFileService.deleteSyncFile(syncFile);

        return;
      }
    } else if (isPendingTypePK(syncFile)) {
      queueSyncWatchEvent(syncFile.getFilePathName(), syncWatchEvent);

      return;
    }

    String type = syncFile.getType();

    if (type.equals(SyncFile.TYPE_FILE)) {
      FileEventUtil.deleteFile(_syncAccountId, syncFile);
    } else {
      FileEventUtil.deleteFolder(_syncAccountId, syncFile);
    }
  }
  @Test
  public void testDeleteFolderSyncFile() throws Exception {
    List<SyncFile> syncFiles = SyncFileService.findSyncFiles(syncAccount.getSyncAccountId());

    Assert.assertEquals(1, syncFiles.size());

    SyncFile folderSyncFileA =
        SyncFileTestUtil.addFolderSyncFile(
            FileUtil.getFilePathName(filePathName, "a"), syncAccount.getSyncAccountId());

    SyncFile folderSyncFileAA =
        SyncFileTestUtil.addFolderSyncFile(
            FileUtil.getFilePathName(filePathName, "a", "a"),
            folderSyncFileA.getTypePK(),
            syncAccount.getSyncAccountId());

    SyncFileTestUtil.addFolderSyncFile(
        FileUtil.getFilePathName(filePathName, "a", "b"),
        folderSyncFileA.getTypePK(),
        syncAccount.getSyncAccountId());

    SyncFileTestUtil.addFolderSyncFile(
        FileUtil.getFilePathName(filePathName, "a", "a", "a"),
        folderSyncFileAA.getTypePK(),
        syncAccount.getSyncAccountId());

    SyncFileTestUtil.addFileSyncFile(
        FileUtil.getFilePathName(filePathName, "a", "b.txt"),
        folderSyncFileA.getTypePK(),
        syncAccount.getSyncAccountId());

    SyncFileTestUtil.addFileSyncFile(
        FileUtil.getFilePathName(filePathName, "a", "c.txt"),
        folderSyncFileA.getTypePK(),
        syncAccount.getSyncAccountId());

    SyncFileTestUtil.addFileSyncFile(
        FileUtil.getFilePathName(filePathName, "a", "a", "a.txt"),
        folderSyncFileAA.getTypePK(),
        syncAccount.getSyncAccountId());

    syncFiles = SyncFileService.findSyncFiles(syncAccount.getSyncAccountId());

    Assert.assertEquals(8, syncFiles.size());

    SyncFileService.deleteSyncFile(folderSyncFileA);

    syncFiles = SyncFileService.findSyncFiles(syncAccount.getSyncAccountId());

    Assert.assertEquals(1, syncFiles.size());
  }
  public static void fireDeleteEvents(Path filePath) throws IOException {
    long startTime = System.currentTimeMillis();

    Files.walkFileTree(
        filePath,
        new SimpleFileVisitor<Path>() {

          @Override
          public FileVisitResult preVisitDirectory(
              Path filePath, BasicFileAttributes basicFileAttributes) {

            SyncFile syncFile = SyncFileService.fetchSyncFile(filePath.toString());

            if (syncFile == null) {
              syncFile = SyncFileService.fetchSyncFile(FileKeyUtil.getFileKey(filePath));
            }

            if (syncFile != null) {
              syncFile.setLocalSyncTime(System.currentTimeMillis());

              SyncFileService.update(syncFile);
            }

            return FileVisitResult.CONTINUE;
          }

          @Override
          public FileVisitResult visitFile(Path filePath, BasicFileAttributes basicFileAttributes) {

            SyncFile syncFile = SyncFileService.fetchSyncFile(filePath.toString());

            if (syncFile == null) {
              syncFile = SyncFileService.fetchSyncFile(FileKeyUtil.getFileKey(filePath));
            }

            if (syncFile != null) {
              syncFile.setLocalSyncTime(System.currentTimeMillis());

              SyncFileService.update(syncFile);
            }

            return FileVisitResult.CONTINUE;
          }
        });

    List<SyncFile> deletedSyncFiles = SyncFileService.findSyncFiles(filePath.toString(), startTime);

    for (SyncFile deletedSyncFile : deletedSyncFiles) {
      if (deletedSyncFile.getTypePK() == 0) {
        SyncFileService.deleteSyncFile(deletedSyncFile, false);

        continue;
      }

      if (deletedSyncFile.isFolder()) {
        FileEventUtil.deleteFolder(deletedSyncFile.getSyncAccountId(), deletedSyncFile);
      } else {
        FileEventUtil.deleteFile(deletedSyncFile.getSyncAccountId(), deletedSyncFile);
      }
    }
  }
 public static void deleteSyncFile(SyncFile syncFile) {
   deleteSyncFile(syncFile, true);
 }