public void buildPatch()

in changes-patch-builder/src/jetbrains/buildServer/vcs/patches/ChangesPatchBuilder.java [39:179]


  public void buildPatch(@NotNull PatchBuilder builder,
                         @NotNull List<VcsChange> changes,
                         @NotNull FileContentProvider provider,
                         boolean strictErrorChecking)
    throws IOException, VcsException {
    LOG.debug("Start building minimal patch for collected changes");

    myStrict = strictErrorChecking;

    final MemoryFileSystem positive = new MemoryFileSystem();
    final MemoryFileSystem negative = new MemoryFileSystem();

    for (final VcsChange change : changes) {
      Assert.isNotNull(change, "Change is null");
      LOG.debug("Vcs change" + change);

      final String path = change.getFileName();
      if (!MemoryFileSystem.checkPath(path))
        throw new VcsException((new StringBuilder()).append("Incorrect path ").append(path).toString());
      final VcsChangeInfo.Type type = change.getType();

      try {
        switch (type)
        {
          case ADDED:
            if (!positive.containsAncestor(path) && negative.containsAncestor(path)) {
              fail((new StringBuilder()).append("Parent directory has been deleted, can't create a file ").append(path).append(" there").toString());
            } else {
              if (negative.containsFile(path)) {
                negative.deleteFile(path);
                positive.writeFile(path);
              } else {
                positive.createFile(path);
              }
              myVersions.put(path, change.getAfterChangeRevisionNumber());
            }
            break;

          case CHANGED:
            if (!positive.containsAncestor(path) && negative.containsAncestor(path))
              fail((new StringBuilder()).append("Parent directory has been deleted, can't modify a file ").append(path).append(" there").toString());
            else if (negative.containsFile(path)) {
              fail((new StringBuilder()).append("Cannot modify a deleted file ").append(path).toString());
            } else {
              if (!positive.containsFile(path))
                positive.writeFile(path);
              myVersions.put(path, change.getAfterChangeRevisionNumber());
            }
            break;

          case REMOVED:
            if (!positive.containsAncestor(path) && negative.containsAncestor(path)) {
              fail((new StringBuilder()).append("Parent directory for ").append(path).append(" has already been deleted").toString());
            } else {
              if (!positive.containsNewFile(path))
                negative.createFile(path);
              if (positive.containsFile(path))
                positive.deleteFile(path);
              myVersions.remove(path);
            }
            break;

          case DIRECTORY_ADDED:
            if (!positive.containsAncestor(path) && negative.containsAncestor(path)) {
              fail((new StringBuilder()).append("Parent directory has been deleted, can't create a directory ").append(path).append(" there").toString());
            } else if (positive.containsNode(path) && !negative.containsNode(path)) {
              fail((new StringBuilder()).append("Directory ").append(path).append(" already added").toString());
            } else {
              positive.createDirectory(path);
            }
            break;

          case DIRECTORY_REMOVED:
            if (positive.containsDirectory(path)) {
              positive.deleteDirectory(path);
            } else {
              if (positive.containsNode(path)) {
                positive.deleteDirectory(path);
              } else {
                if (negative.containsAncestor(path))
                  fail((new StringBuilder()).append("Parent directory for ").append(path).append(" has already been deleted").toString());
                if (negative.containsDirectory(path))
                  fail((new StringBuilder()).append("Directory ").append(path).append(" has already been deleted").toString());
              }
              if (negative.containsNode(path))
                negative.deleteDirectory(path);
              negative.createDirectory(path);
            }
            break;

          default:
            fail((new StringBuilder()).append("Unexpected VCS change type: ").append(type).toString());
            break;
        }
      }
      catch (FileSystemException e) {
        fail(e);
      }
      catch (AssertionFailedException e) {
        fail(e);
      }      
    }

    final ArrayList<String> newFiles = new ArrayList<String>();
    final ArrayList<String> modifiedFiles = new ArrayList<String>();
    final ArrayList<String> newDirectories = new ArrayList<String>();
    positive.toCollections(newFiles, modifiedFiles, newDirectories);

    final ArrayList<String> deletedFiles = new ArrayList<String>();
    final ArrayList<String> deletedDirectories = new ArrayList<String>();
    negative.toCollections(deletedFiles, deletedFiles, deletedDirectories);

    for (String path : deletedFiles) {
      LOG.debug("Delete file in patch: " + path);
      builder.deleteFile(new File(path), false);
    }
    for (String path : deletedDirectories) {
      LOG.debug("Delete folder in patch: " + path);
      builder.deleteDirectory(new File(path), false);
    }
    for (String path : newDirectories) {
      LOG.debug("Create folder in patch: " + path);
      builder.createDirectory(new File(path));
    }
    for (String path : newFiles) {
      final String version = myVersions.get(path);
      LOG.debug("Create file in patch: " + path + " version: " + version);
      if (version == null)
        throw new VcsException((new StringBuilder()).append("Unexpected error: No version for ").append(path).append(" prepared").toString());
      final File content = provider.getFile(path, version);
      builder.createBinaryFile(new File(path), version, new FileInputStream(content), content.length());
    }
    for (String path : modifiedFiles) {
      final String version = myVersions.get(path);
      LOG.debug("Changed file in patch: " + path + " version: " + version);
      if (version == null)
        throw new VcsException((new StringBuilder()).append("Unexpected error: No version for ").append(path).append(" prepared").toString());
      final File content = provider.getFile(path, version);
      builder.changeOrCreateBinaryFile(new File(path), version, new FileInputStream(content), content.length());
    }    
  }