<commit_before>package org.smoothbuild.lang.builtin.java;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

import org.smoothbuild.io.cache.value.build.BlobBuilder;
import org.smoothbuild.io.fs.base.Path;
import org.smoothbuild.io.fs.base.exc.FileSystemException;
import org.smoothbuild.lang.builtin.compress.Constants;
import org.smoothbuild.lang.builtin.java.err.CannotAddDuplicatePathError;
import org.smoothbuild.lang.plugin.PluginApi;
import org.smoothbuild.lang.plugin.Required;
import org.smoothbuild.lang.plugin.SmoothFunction;
import org.smoothbuild.lang.type.SArray;
import org.smoothbuild.lang.type.SBlob;
import org.smoothbuild.lang.type.SFile;
import org.smoothbuild.message.listen.ErrorMessageException;
import org.smoothbuild.util.DuplicatesDetector;

public class JarFunction {

  public interface Parameters {
    @Required
    public SArray<SFile> files();

    public SBlob manifest();
  }

  @SmoothFunction(name = "jar")
  public static SBlob execute(PluginApi pluginApi, Parameters params) {
    return new Worker(pluginApi, params).execute();
  }

  private static class Worker {
    private final PluginApi pluginApi;
    private final Parameters params;

    private final byte[] buffer = new byte[Constants.BUFFER_SIZE];
    private final DuplicatesDetector<Path> duplicatesDetector;

    public Worker(PluginApi pluginApi, Parameters params) {
      this.pluginApi = pluginApi;
      this.params = params;
      this.duplicatesDetector = new DuplicatesDetector<Path>();
    }

    public SBlob execute() {
      BlobBuilder blobBuilder = pluginApi.blobBuilder();
      try (JarOutputStream jarOutputStream = createOutputStream(blobBuilder);) {
        for (SFile file : params.files()) {
          addEntry(jarOutputStream, file);
        }
      } catch (IOException e) {
        throw new FileSystemException(e);
      }

      return blobBuilder.build();
    }

    private JarOutputStream createOutputStream(BlobBuilder blobBuilder) throws IOException {
      OutputStream outputStream = blobBuilder.openOutputStream();
      if (params.manifest() == null) {
        return new JarOutputStream(outputStream);
      } else {
        Manifest manifest = new Manifest(params.manifest().openInputStream());
        return new JarOutputStream(outputStream, manifest);
      }
    }

    private void addEntry(JarOutputStream jarOutputStream, SFile file) throws IOException {
      Path path = file.path();
      if (duplicatesDetector.addValue(path)) {
        throw new ErrorMessageException(new CannotAddDuplicatePathError(path));
      }
      JarEntry entry = new JarEntry(path.value());
      jarOutputStream.putNextEntry(entry);

      try (InputStream inputStream = file.content().openInputStream();) {
        int readCount = inputStream.read(buffer);
        while (readCount > 0) {
          jarOutputStream.write(buffer, 0, readCount);
          readCount = inputStream.read(buffer);
        }
      }

      jarOutputStream.closeEntry();
    }
  }
}
<commit_msg>fixed JarFunction to close all streams correctly<commit_after>package org.smoothbuild.lang.builtin.java;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

import org.smoothbuild.io.cache.value.build.BlobBuilder;
import org.smoothbuild.io.fs.base.Path;
import org.smoothbuild.io.fs.base.exc.FileSystemException;
import org.smoothbuild.lang.builtin.compress.Constants;
import org.smoothbuild.lang.builtin.java.err.CannotAddDuplicatePathError;
import org.smoothbuild.lang.plugin.PluginApi;
import org.smoothbuild.lang.plugin.Required;
import org.smoothbuild.lang.plugin.SmoothFunction;
import org.smoothbuild.lang.type.SArray;
import org.smoothbuild.lang.type.SBlob;
import org.smoothbuild.lang.type.SFile;
import org.smoothbuild.message.listen.ErrorMessageException;
import org.smoothbuild.util.DuplicatesDetector;

public class JarFunction {

  public interface Parameters {
    @Required
    public SArray<SFile> files();

    public SBlob manifest();
  }

  @SmoothFunction(name = "jar")
  public static SBlob execute(PluginApi pluginApi, Parameters params) {
    return new Worker(pluginApi, params).execute();
  }

  private static class Worker {
    private final PluginApi pluginApi;
    private final Parameters params;

    private final byte[] buffer = new byte[Constants.BUFFER_SIZE];
    private final DuplicatesDetector<Path> duplicatesDetector;

    public Worker(PluginApi pluginApi, Parameters params) {
      this.pluginApi = pluginApi;
      this.params = params;
      this.duplicatesDetector = new DuplicatesDetector<Path>();
    }

    public SBlob execute() {
      BlobBuilder blobBuilder = pluginApi.blobBuilder();
      try (JarOutputStream jarOutputStream = createOutputStream(blobBuilder);) {
        for (SFile file : params.files()) {
          addEntry(jarOutputStream, file);
        }
      } catch (IOException e) {
        throw new FileSystemException(e);
      }

      return blobBuilder.build();
    }

    private JarOutputStream createOutputStream(BlobBuilder blobBuilder) throws IOException {
      OutputStream outputStream = blobBuilder.openOutputStream();
      if (params.manifest() == null) {
        return new JarOutputStream(outputStream);
      } else {
        try (InputStream manifestStream = params.manifest().openInputStream();) {
          Manifest manifest = new Manifest(manifestStream);
          return new JarOutputStream(outputStream, manifest);
        }
      }
    }

    private void addEntry(JarOutputStream jarOutputStream, SFile file) throws IOException {
      Path path = file.path();
      if (duplicatesDetector.addValue(path)) {
        throw new ErrorMessageException(new CannotAddDuplicatePathError(path));
      }
      JarEntry entry = new JarEntry(path.value());
      jarOutputStream.putNextEntry(entry);

      try (InputStream inputStream = file.content().openInputStream();) {
        int readCount = inputStream.read(buffer);
        while (readCount > 0) {
          jarOutputStream.write(buffer, 0, readCount);
          readCount = inputStream.read(buffer);
        }
      }

      jarOutputStream.closeEntry();
    }
  }
}

{'fraction_non_alphanumeric': 0.09837092731829573, 'fraction_numerical': 0.0006265664160401002, 'mean_word_length': 3.72962962962963, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6985361', 'n_tokens_mistral': 1795, 'n_tokens_neox': 1727, 'n_words': 382}