<commit_before>package org.jbehave.web.io;

import static org.apache.commons.lang.StringUtils.removeEnd;
import static org.apache.commons.lang.StringUtils.removeStart;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.io.IOUtils;

/**
 * File archiver for zip files
 */
public class ZipFileArchiver implements FileArchiver {

	private static final String ZIP = "zip";
	private static final String ZIP_EXT = ".zip";
	private ArchiveStreamFactory factory = new ArchiveStreamFactory();

	public boolean isArchive(File file) {
		return file.getName().endsWith(ZIP_EXT);
	}

	public void archive(File archive, File directory) {
		try {
			ArchiveOutputStream out = factory.createArchiveOutputStream(ZIP,
					new FileOutputStream(archive));
			List<File> files = listContent(directory);
			for (File file : files) {
				if (!file.isDirectory()) {
					ZipArchiveEntry entry = new ZipArchiveEntry(relativeTo(
							file, directory).getPath());
					zipEntry(entry, out, file);
				}
			}
			out.close();
		} catch (Exception e) {
			throw new FileArchiveFailedException(archive, directory, e);
		}
	}

	public File relativeTo(File file, File directory) {
		return new File(removeStart(file.getPath(), directory.getPath() + "/"));
	}

	private void zipEntry(ZipArchiveEntry entry, ArchiveOutputStream out,
			File file) throws IOException, FileNotFoundException {
		out.putArchiveEntry(entry);
		IOUtils.copy(new FileInputStream(file), out);
		out.closeArchiveEntry();
	}

	public File directoryOf(File archive) {
		return new File(removeEnd(archive.getPath(), ZIP_EXT));
	}

	public void unarchive(File archive, File directory) {
		InputStream is = null;
		ArchiveInputStream in = null;
		try {
			is = new FileInputStream(archive);
			in = factory.createArchiveInputStream(ZIP, is);
			ZipArchiveEntry entry = null;
			while ((entry = (ZipArchiveEntry) in.getNextEntry()) != null) {
				unzipEntry(entry, in, directory);
			}
		} catch (Exception e) {
			throw new FileUnarchiveFailedException(archive, directory, e);
		} finally {
			close(is);
 			close(in);
		}
	}

	private void close(InputStream is) {
		try {
			if (is != null) {
				is.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<File> listContent(File file) {
		List<File> content = new ArrayList<File>();
		content.add(normalisePath(file));
		if (file.isDirectory()) {
			for (File child : file.listFiles()) {
				content.addAll(listContent(child));
			}
		}
		return content;
	}

	private File normalisePath(File file) {
		return new File(file.getPath().replace('\\', '/'));
	}

	private void unzipEntry(ZipArchiveEntry entry, InputStream in,
			File directory) throws IOException {

		if (entry.isDirectory()) {
			createDir(new File(directory, entry.getName()));
			return;
		}

		File outputFile = new File(directory, entry.getName());
		createDir(outputFile.getParentFile());
		copy(entry, in, outputFile);

	}

	private void createDir(File dir) throws IOException {
		if (dir.exists()) {<commit_msg>Normalise paths to correctly extract relative path.<commit_after>package org.jbehave.web.io;

import static org.apache.commons.lang.StringUtils.removeEnd;
import static org.apache.commons.lang.StringUtils.removeStart;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.io.IOUtils;

/**
 * File archiver for zip files
 */
public class ZipFileArchiver implements FileArchiver {

	private static final String ZIP = "zip";
	private static final String ZIP_EXT = ".zip";
	private ArchiveStreamFactory factory = new ArchiveStreamFactory();

	public boolean isArchive(File file) {
		return file.getName().endsWith(ZIP_EXT);
	}

	public void archive(File archive, File directory) {
		try {
			ArchiveOutputStream out = factory.createArchiveOutputStream(ZIP,
					new FileOutputStream(archive));
			List<File> files = listContent(directory);
			for (File file : files) {
				if (!file.isDirectory()) {
					ZipArchiveEntry entry = new ZipArchiveEntry(relativeTo(
							file, directory).getPath());
					zipEntry(entry, out, file);
				}
			}
			out.close();
		} catch (Exception e) {
			throw new FileArchiveFailedException(archive, directory, e);
		}
	}

	public File relativeTo(File file, File directory) {
		return new File(removeStart(normalisePath(file.getPath()), normalisePath(directory.getPath()) + "/"));
	}

	private String normalisePath(String path) {
		return path.replace('\\', '/');
	}
	
	private void zipEntry(ZipArchiveEntry entry, ArchiveOutputStream out,
			File file) throws IOException, FileNotFoundException {
		out.putArchiveEntry(entry);
		IOUtils.copy(new FileInputStream(file), out);
		out.closeArchiveEntry();
	}

	public File directoryOf(File archive) {
		return new File(removeEnd(archive.getPath(), ZIP_EXT));
	}

	public void unarchive(File archive, File directory) {
		InputStream is = null;
		ArchiveInputStream in = null;
		try {
			is = new FileInputStream(archive);
			in = factory.createArchiveInputStream(ZIP, is);
			ZipArchiveEntry entry = null;
			while ((entry = (ZipArchiveEntry) in.getNextEntry()) != null) {
				unzipEntry(entry, in, directory);
			}
		} catch (Exception e) {
			throw new FileUnarchiveFailedException(archive, directory, e);
		} finally {
			close(is);
 			close(in);
		}
	}

	private void close(InputStream is) {
		try {
			if (is != null) {
				is.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<File> listContent(File file) {
		List<File> content = new ArrayList<File>();
		content.add(file);
		if (file.isDirectory()) {
			for (File child : file.listFiles()) {
				content.addAll(listContent(child));
			}
		}
		return content;
	}

	private void unzipEntry(ZipArchiveEntry entry, InputStream in,
			File directory) throws IOException {

		if (entry.isDirectory()) {
			createDir(new File(directory, entry.getName()));
			return;
		}

		File outputFile = new File(directory, entry.getName());
		createDir(outputFile.getParentFile());
		copy(entry, in, outputFile);

	}

	private void createDir(File dir) throws IOException {
		if (dir.exists()) {
{'fraction_non_alphanumeric': 0.119534355479841, 'fraction_numerical': 0.0, 'mean_word_length': 4.516836335160533, 'pattern_counts': {'":': 0, '<': 11, '<?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': '6645761', 'n_tokens_mistral': 2385, 'n_tokens_neox': 2085, 'n_words': 513}