@Override
  public void perform(Run<?, ?> build, FilePath ws, Launcher launcher, TaskListener listener)
      throws InterruptedException {
    if (artifacts.length() == 0) {
      listener.error(Messages.ArtifactArchiver_NoIncludes());
      build.setResult(Result.FAILURE);
      return;
    }

    if (onlyIfSuccessful
        && build.getResult() != null
        && build.getResult().isWorseThan(Result.UNSTABLE)) {
      listener.getLogger().println(Messages.ArtifactArchiver_SkipBecauseOnlyIfSuccessful());
      return;
    }

    listener.getLogger().println(Messages.ArtifactArchiver_ARCHIVING_ARTIFACTS());
    try {
      String artifacts = build.getEnvironment(listener).expand(this.artifacts);

      Map<String, String> files =
          ws.act(new ListFiles(artifacts, excludes, defaultExcludes, caseSensitive));
      if (!files.isEmpty()) {
        build
            .pickArtifactManager()
            .archive(ws, launcher, BuildListenerAdapter.wrap(listener), files);
        if (fingerprint) {
          new Fingerprinter(artifacts).perform(build, ws, launcher, listener);
        }
      } else {
        Result result = build.getResult();
        if (result != null && result.isBetterOrEqualTo(Result.UNSTABLE)) {
          // If the build failed, don't complain that there was no matching artifact.
          // The build probably didn't even get to the point where it produces artifacts.
          listenerWarnOrError(listener, Messages.ArtifactArchiver_NoMatchFound(artifacts));
          String msg = null;
          try {
            msg =
                ws.validateAntFileMask(
                    artifacts, FilePath.VALIDATE_ANT_FILE_MASK_BOUND, caseSensitive);
          } catch (Exception e) {
            listenerWarnOrError(listener, e.getMessage());
          }
          if (msg != null) listenerWarnOrError(listener, msg);
        }
        if (!allowEmptyArchive) {
          build.setResult(Result.FAILURE);
        }
        return;
      }
    } catch (IOException e) {
      Util.displayIOException(e, listener);
      e.printStackTrace(listener.error(Messages.ArtifactArchiver_FailedToArchive(artifacts)));
      build.setResult(Result.FAILURE);
      return;
    }
  }
    protected void check() throws IOException, ServletException {
      String value = fixEmpty(request.getParameter("value"));
      AbstractProject<?, ?> p = (AbstractProject<?, ?>) subject;

      if (value == null || p == null) {
        ok(); // none entered yet, or something is seriously wrong
        return;
      }

      try {
        FilePath ws = getBaseDirectory(p);

        if (ws == null || !ws.exists()) { // no workspace. can't check
          ok();
          return;
        }

        String msg = ws.validateAntFileMask(value);
        if (errorIfNotExist) error(msg);
        else warning(msg);
      } catch (InterruptedException e) {
        ok(); // coundn't check
      }
    }
  @Override
  public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
      throws InterruptedException {
    Result criteriaResult = CloneWorkspaceUtil.getResultForCriteria(criteria);

    String realIncludeGlob;
    // Default to **/* if no glob is specified.
    if (workspaceGlob.length() == 0) {
      realIncludeGlob = "**/*";
    } else {
      try {
        realIncludeGlob = build.getEnvironment(listener).expand(workspaceGlob);
      } catch (IOException e) {
        // We couldn't get an environment for some reason, so we'll just use the original.
        realIncludeGlob = workspaceGlob;
      }
    }

    String realExcludeGlob = null;
    // Default to empty if no glob is specified.
    if (Util.fixNull(workspaceExcludeGlob).length() != 0) {
      try {
        realExcludeGlob = build.getEnvironment(listener).expand(workspaceExcludeGlob);
      } catch (IOException e) {
        // We couldn't get an environment for some reason, so we'll just use the original.
        realExcludeGlob = workspaceExcludeGlob;
      }
    }

    if (build.getResult().isBetterOrEqualTo(criteriaResult)) {
      listener.getLogger().println(Messages.CloneWorkspacePublisher_ArchivingWorkspace());
      FilePath ws = build.getWorkspace();
      if (ws == null) { // #3330: slave down?
        return true;
      }

      try {

        String includeMsg = ws.validateAntFileMask(realIncludeGlob);
        String excludeMsg = null;
        if (realExcludeGlob != null) {
          ws.validateAntFileMask(realExcludeGlob);
        }
        // This means we found something.
        if ((includeMsg == null) && (excludeMsg == null)) {
          DirScanner globScanner = new DirScanner.Glob(realIncludeGlob, realExcludeGlob);
          build.addAction(snapshot(build, ws, globScanner, listener, archiveMethod));

          // Find the next most recent build meeting this criteria with an archived snapshot.
          AbstractBuild<?, ?> previousArchivedBuild =
              CloneWorkspaceUtil.getMostRecentBuildForCriteriaWithSnapshot(
                  build.getPreviousBuild(), criteria);

          if (previousArchivedBuild != null) {
            listener
                .getLogger()
                .println(
                    Messages.CloneWorkspacePublisher_DeletingOld(
                        previousArchivedBuild.getDisplayName()));
            try {
              File oldWss =
                  new File(
                      previousArchivedBuild.getRootDir(),
                      CloneWorkspaceUtil.getFileNameForMethod(archiveMethod));
              Util.deleteFile(oldWss);
            } catch (IOException e) {
              e.printStackTrace(listener.error(e.getMessage()));
            }
          }

          return true;
        } else {
          listener
              .getLogger()
              .println(Messages.CloneWorkspacePublisher_NoMatchFound(realIncludeGlob, includeMsg));
          return true;
        }
      } catch (IOException e) {
        Util.displayIOException(e, listener);
        e.printStackTrace(
            listener.error(Messages.CloneWorkspacePublisher_FailedToArchive(realIncludeGlob)));
        return true;
      } catch (InterruptedException e) {
        e.printStackTrace(
            listener.error(Messages.CloneWorkspacePublisher_FailedToArchive(realIncludeGlob)));
        return true;
      }

    } else {
      listener.getLogger().println(Messages.CloneWorkspacePublisher_CriteriaNotMet(criteriaResult));
      return true;
    }
  }