public static Collection execute()

in plugin/src/com/microsoft/alm/plugin/idea/tfvc/core/tfs/operations/ScheduleForDeletion.java [57:185]


    public static Collection<VcsException> execute(final Project project, final List<FilePath> files) {
        // choose roots
        // find if changes need reverted and revert them
        // schedule roots for deletion using their original names

        final Collection<VcsException> errors = new ArrayList<>();

        final List<String> filePaths = new ArrayList<>(files.size());
        for (final FilePath filePath : files) {
            filePaths.add(filePath.getPath());
        }

        try {
            final List<PendingChange> pendingChanges = new ArrayList<>();
            final List<String> revert = new ArrayList<>();
            final Set<String> scheduleForDeletion = new HashSet<>();
            final ServerContext context = TFSVcs.getInstance(project).getServerContext(true);

            TfvcClient client = TfvcClient.getInstance();
            for (final String path : filePaths) {
                List<PendingChange> fileChanges = client.getStatusForFiles(project, context, ImmutableList.of(path));

                // deleting a file that has no changes
                if (fileChanges.isEmpty()) {
                    scheduleForDeletion.add(path);
                } else {
                    pendingChanges.addAll(fileChanges);
                }
            }

            for (final PendingChange pendingChange : pendingChanges) {
                StatusProvider.visitByStatus(new StatusProvider.StatusAdapter() {

                    public void unversioned(final @NotNull FilePath localPath, final boolean localItemExists,
                                            final @NotNull ServerStatus serverStatus) {
                        // if an unversioned delete, IDE has already deleted the file and now TFVC has to delete it
                        if (pendingChange.getChangeTypes().contains(ServerStatusType.DELETE)) {
                            logger.info("ScheduleForDeletion: unversioned deleted file " + localPath.getPath());
                            scheduleForDeletion.add(StringUtils.isNotEmpty(pendingChange.getSourceItem()) ? pendingChange.getSourceItem() : pendingChange.getLocalItem());
                        } else {
                            // do nothing because file isn't recognized
                            logger.info("ScheduleForDeletion: do nothing for unversioned file " + localPath.getPath());
                        }
                    }

                    public void checkedOutForEdit(final @NotNull FilePath localPath, final boolean localItemExists,
                                                  final @NotNull ServerStatus serverStatus) {
                        logger.info("ScheduleForDeletion: checkedOutForEdit file " + localPath.getPath());
                        revert.add(pendingChange.getLocalItem());
                        scheduleForDeletion.add(pendingChange.getLocalItem());
                    }

                    public void scheduledForAddition(final @NotNull FilePath localPath, final boolean localItemExists,
                                                     final @NotNull ServerStatus serverStatus) {
                        logger.info("ScheduleForDeletion: scheduledForAddition file " + localPath.getPath());
                        revert.add(pendingChange.getLocalItem());
                    }

                    public void scheduledForDeletion(final @NotNull FilePath localPath, final boolean localItemExists,
                                                     final @NotNull ServerStatus serverStatus) {
                        logger.warn("ScheduleForDeletion: " + localPath + " already is deleted");
                    }

                    public void renamed(final @NotNull FilePath localPath, final boolean localItemExists,
                                        final @NotNull ServerStatus serverStatus) {
                        logger.info("ScheduleForDeletion: renamed file " + localPath.getPath());
                        // revert local path but delete the source path since that is the original path before the rename
                        revert.add(pendingChange.getLocalItem());
                        scheduleForDeletion.add(pendingChange.getSourceItem());
                    }

                    public void renamedCheckedOut(final @NotNull FilePath localPath, final boolean localItemExists,
                                                  final @NotNull ServerStatus serverStatus) {
                        logger.info("ScheduleForDeletion: renamedCheckedOut file " + localPath.getPath());
                        // revert local path but delete the source path since that is the original path before the rename
                        revert.add(pendingChange.getLocalItem());
                        scheduleForDeletion.add(pendingChange.getSourceItem());
                    }

                    public void undeleted(final @NotNull FilePath localPath, final boolean localItemExists,
                                          final @NotNull ServerStatus serverStatus) {
                        logger.info("ScheduleForDeletion: undeleted file " + localPath.getPath());
                        revert.add(pendingChange.getLocalItem());
                    }
                }, pendingChange);
            }

            if (!revert.isEmpty()) {
                List<TfsPath> pathsForUndo = revert.stream().map(TfsLocalPath::new).collect(Collectors.toList());
                client.undoLocalChanges(project, context, pathsForUndo);
            }

            final List<String> confirmedDeletedFiles = new ArrayList<>();
            if (!scheduleForDeletion.isEmpty()) {
                // a workspace is needed since some paths are server paths, all changes will have the same workspace so
                // just get it from the first change (list isn't empty since deletes were found)
                // if no pending changes exist a workspace isn't needed b/c a local path is being used
                final String workspace;
                if (!pendingChanges.isEmpty()) {
                    workspace = pendingChanges.get(0).getWorkspace();
                } else {
                    workspace = StringUtils.EMPTY;
                }

                TfvcDeleteResult deleteResult = CommandUtils.deleteFiles(
                        context,
                        new ArrayList<>(scheduleForDeletion),
                        workspace,
                        false);
                deleteResult.throwIfErrorMessagesAreNotEmpty();
                deleteResult.throwIfNotFoundPathsAreNotEmpty();

                List<String> deletedPaths = deleteResult.getDeletedPaths().stream()
                        .map(Path::toString)
                        .collect(Collectors.toList());
                confirmedDeletedFiles.addAll(deletedPaths);
            }

            for (final FilePath expectedDeletedFile : files) {
                if (confirmedDeletedFiles.contains(expectedDeletedFile.getPath())) {
                    TfsFileUtil.markFileDirty(project, expectedDeletedFile);
                }
            }
        } catch (Throwable t) {
            logger.warn("executeDelete experienced a failure while looking for altered files to delete", t);
            errors.add(TFSVcs.convertToVcsException(t));
        }
        return errors;
    }