<commit_before>package org.smoothbuild.builtin.compress;

import static org.smoothbuild.io.fs.base.Path.SEPARATOR;
import static org.smoothbuild.io.fs.base.Path.validationError;

import java.io.IOException;
import java.io.OutputStream;
import java.util.function.Predicate;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.smoothbuild.io.fs.base.FileSystemException;
import org.smoothbuild.lang.message.ErrorMessage;
import org.smoothbuild.lang.plugin.Container;
import org.smoothbuild.lang.plugin.SmoothFunction;
import org.smoothbuild.lang.value.Array;
import org.smoothbuild.lang.value.ArrayBuilder;
import org.smoothbuild.lang.value.Blob;
import org.smoothbuild.lang.value.BlobBuilder;
import org.smoothbuild.lang.value.SFile;
import org.smoothbuild.lang.value.SString;
import org.smoothbuild.util.DuplicatesDetector;

public class UnzipFunction {
  private static final Predicate<String> IS_DIR = (string) -> string.endsWith(SEPARATOR);

  @SmoothFunction
  public static Array<SFile> unzip(Container container, Blob blob) {
    DuplicatesDetector<String> duplicatesDetector = new DuplicatesDetector<>();
    ArrayBuilder<SFile> fileArrayBuilder = container.create().arrayBuilder(SFile.class);
    try {
      try (ZipInputStream zipInputStream = new ZipInputStream(blob.openInputStream())) {
        ZipEntry entry;
        while ((entry = zipInputStream.getNextEntry()) != null) {
          if (!IS_DIR.test(entry.getName())) {
            SFile unzippedEntry = unzipEntry(container, zipInputStream, entry);
            String fileName = unzippedEntry.path().value();
            if (duplicatesDetector.addValue(fileName)) {
              throw new ErrorMessage("Zip file contains two files with the same path = "
                  + fileName);
            }

            fileArrayBuilder.add(unzippedEntry);
          }
        }
      }
      return fileArrayBuilder.build();
    } catch (IOException e) {
      throw new FileSystemException(e);
    }
  }

  private static SFile unzipEntry(Container container, ZipInputStream zipInputStream,
      ZipEntry entry) {
    String fileName = entry.getName();
    String errorMessage = validationError(fileName);
    if (errorMessage != null) {
      throw new ErrorMessage("File in a zip file has illegal name = '" + fileName + "'");
    }

    SString path = container.create().string(fileName);
    Blob content = unzipEntryContent(container, zipInputStream);
    return container.create().file(path, content);
  }

  private static Blob unzipEntryContent(Container container, ZipInputStream zipInputStream) {
    byte[] buffer = new byte[Constants.BUFFER_SIZE];
    try {
      BlobBuilder contentBuilder = container.create().blobBuilder();
      try (OutputStream outputStream = contentBuilder) {
        int len;
        while ((len = zipInputStream.read(buffer)) > 0) {
          outputStream.write(buffer, 0, len);
        }
      }
      return contentBuilder.build();
    } catch (IOException e) {
      throw new FileSystemException(e);
    }
  }
}<commit_msg>refactored UnzipFunction to use ZipFile<commit_after>package org.smoothbuild.builtin.compress;

import static org.smoothbuild.io.fs.base.Path.SEPARATOR;
import static org.smoothbuild.io.fs.base.Path.validationError;
import static org.smoothbuild.util.Streams.copy;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.function.Predicate;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.smoothbuild.io.fs.base.FileSystemException;
import org.smoothbuild.lang.message.ErrorMessage;
import org.smoothbuild.lang.plugin.Container;
import org.smoothbuild.lang.plugin.SmoothFunction;
import org.smoothbuild.lang.value.Array;
import org.smoothbuild.lang.value.ArrayBuilder;
import org.smoothbuild.lang.value.Blob;
import org.smoothbuild.lang.value.BlobBuilder;
import org.smoothbuild.lang.value.SFile;
import org.smoothbuild.lang.value.SString;
import org.smoothbuild.util.DuplicatesDetector;

public class UnzipFunction {
  private static final Predicate<String> IS_DIR = (string) -> string.endsWith(SEPARATOR);

  @SmoothFunction
  public static Array<SFile> unzip(Container container, Blob blob) {
    DuplicatesDetector<String> duplicatesDetector = new DuplicatesDetector<>();
    ArrayBuilder<SFile> fileArrayBuilder = container.create().arrayBuilder(SFile.class);
    try {
      File tempFile = copyToTempFile(blob);
      try (ZipFile zipFile = new ZipFile(tempFile)) {
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        while (entries.hasMoreElements()) {
          ZipEntry entry = entries.nextElement();
          if (!IS_DIR.test(entry.getName())) {
            SFile unzippedEntry = unzipEntry(container, zipFile.getInputStream(entry), entry);
            String fileName = unzippedEntry.path().value();
            if (duplicatesDetector.addValue(fileName)) {
              throw new ErrorMessage("Zip file contains two files with the same path = "
                  + fileName);
            }

            fileArrayBuilder.add(unzippedEntry);
          }
        }
      }
      return fileArrayBuilder.build();
    } catch (IOException e) {
      throw new FileSystemException(e);
    }
  }

  private static File copyToTempFile(Blob blob) throws IOException, FileNotFoundException {
    File tempFile = File.createTempFile("", "");
    copy(blob.openInputStream(), new BufferedOutputStream(new FileOutputStream(tempFile)));
    return tempFile;
  }

  private static SFile unzipEntry(Container container, InputStream inputStream, ZipEntry entry) {
    String fileName = entry.getName();
    String errorMessage = validationError(fileName);
    if (errorMessage != null) {
      throw new ErrorMessage("File in a zip file has illegal name = '" + fileName + "'");
    }

    SString path = container.create().string(fileName);
    Blob content = unzipEntryContent(container, inputStream);
    return container.create().file(path, content);
  }

  private static Blob unzipEntryContent(Container container, InputStream inputStream) {
    byte[] buffer = new byte[Constants.BUFFER_SIZE];
    try {
      BlobBuilder contentBuilder = container.create().blobBuilder();
      try (OutputStream outputStream = contentBuilder) {
        int len;
        while ((len = inputStream.read(buffer)) > 0) {
          outputStream.write(buffer, 0, len);
        }
      }
      return contentBuilder.build();
    } catch (IOException e) {
      throw new FileSystemException(e);
    }
  }
}
{'fraction_non_alphanumeric': 0.10553814002089865, 'fraction_numerical': 0.0005971040453799074, 'mean_word_length': 3.711673699015471, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 18, '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': '2496685', 'n_tokens_mistral': 1909, 'n_tokens_neox': 1847, 'n_words': 413}