com.lazerycode.selenium.extract.FileExtractor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of driver-binary-downloader-maven-plugin Show documentation
Show all versions of driver-binary-downloader-maven-plugin Show documentation
A plugin to automatically download individual selenium standalone binaries (e.g. chromedriver.exe) for your mavenised selenium project.
The newest version!
package com.lazerycode.selenium.extract;
import com.lazerycode.selenium.exceptions.ExpectedFileNotFoundException;
import com.lazerycode.selenium.repository.BinaryType;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.input.CloseShieldInputStream;
import org.apache.log4j.Logger;
import org.apache.maven.plugin.MojoFailureException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import static com.lazerycode.selenium.extract.DownloadableFileType.TAR;
public class FileExtractor {
private static final Logger LOG = Logger.getLogger(FileExtractor.class);
private final boolean overwriteFilesThatExist;
/**
* @param overwriteFilesThatExist Overwrite any existing files
*/
public FileExtractor(boolean overwriteFilesThatExist) {
this.overwriteFilesThatExist = overwriteFilesThatExist;
}
/**
* Extract binary from a downloaded archive file
*
* @param downloadedCompressedFile The downloaded compressed file
* @param extractedToFilePath Path to extracted file
* @param possibleFilenames Names of the files we want to extract
* @return boolean
* @throws IOException Unable to write to filesystem
* @throws IllegalArgumentException Unsupported archive
* @throws MojoFailureException Error running plugin
*/
public String extractFileFromArchive(File downloadedCompressedFile, String extractedToFilePath, BinaryType possibleFilenames) throws IOException, IllegalArgumentException, MojoFailureException {
DownloadableFileType fileType = DownloadableFileType.valueOf(FilenameUtils.getExtension(downloadedCompressedFile.getName()).toUpperCase());
LOG.debug("Determined archive type: " + fileType);
LOG.debug("Overwrite files that exist: " + overwriteFilesThatExist);
switch (fileType) {
case GZ:
case BZ2:
CompressedFile compressedFile = new CompressedFile(downloadedCompressedFile);
if (null != compressedFile.getArchiveType() && compressedFile.getArchiveType().equals(TAR)) {
return untarFile(compressedFile.getInputStream(), extractedToFilePath, possibleFilenames);
} else {
return copyFileToDisk(compressedFile.getInputStream(), extractedToFilePath, compressedFile.getDecompressedFilename());
}
case ZIP:
return unzipFile(downloadedCompressedFile, extractedToFilePath, possibleFilenames);
case EXE:
if (possibleFilenames.getBinaryFilenames().contains(downloadedCompressedFile.getName())) {
return copyFileToDisk(new FileInputStream(downloadedCompressedFile), extractedToFilePath, downloadedCompressedFile.getName());
}
default:
throw new IllegalArgumentException("." + fileType + " is an unsupported archive type");
}
}
/**
* Unzip a downloaded zip file (this will implicitly overwrite any existing files)
*
* @param downloadedCompressedFile The downloaded zip file
* @param extractedToFilePath Path to extracted file
* @param possibleFilenames Names of the files we want to extract
* @return boolean
* @throws IOException IOException
*/
String unzipFile(File downloadedCompressedFile, String extractedToFilePath, BinaryType possibleFilenames) throws IOException, ExpectedFileNotFoundException {
LOG.debug("Attempting to extract binary from .zip file...");
ArrayList filenamesWeAreSearchingFor = new ArrayList(possibleFilenames.getBinaryFilenames());
ZipFile zip = new ZipFile(downloadedCompressedFile);
try {
Enumeration zipFile = zip.getEntries();
if (filenamesWeAreSearchingFor.get(0).equals("*")) {
filenamesWeAreSearchingFor.remove(0);
LOG.debug("Extracting full archive");
return this.unzipFolder(zip, extractedToFilePath, filenamesWeAreSearchingFor);
} else {
while (zipFile.hasMoreElements()) {
ZipArchiveEntry zipFileEntry = zipFile.nextElement();
for (String aFilenameWeAreSearchingFor : filenamesWeAreSearchingFor) {
if (zipFileEntry.getName().endsWith(aFilenameWeAreSearchingFor)) {
LOG.debug("Found: " + zipFileEntry.getName());
return copyFileToDisk(zip.getInputStream(zipFileEntry), extractedToFilePath, aFilenameWeAreSearchingFor);
}
}
}
}
} finally {
zip.close();
}
throw new ExpectedFileNotFoundException("Unable to find any expected files for " + possibleFilenames.getBinaryTypeAsString());
}
/**
* Untar a decompressed tar file (this will implicitly overwrite any existing files)
*
* @param compressedFileInputStream The expanded tar file
* @param extractedToFilePath Path to extracted file
* @param possibleFilenames Names of the files we want to extract
* @return boolean
* @throws IOException MojoFailureException
*/
private String untarFile(InputStream compressedFileInputStream, String extractedToFilePath, BinaryType possibleFilenames) throws IOException, ExpectedFileNotFoundException {
LOG.debug("Attempting to extract binary from a .tar file...");
ArchiveEntry currentFile;
ArrayList filenamesWeAreSearchingFor = new ArrayList(possibleFilenames.getBinaryFilenames());
try {
if (filenamesWeAreSearchingFor.contains("*")) {
filenamesWeAreSearchingFor.remove(0);
LOG.debug("Extracting full archive");
return this.untarFolder(compressedFileInputStream, extractedToFilePath, filenamesWeAreSearchingFor);
} else {
ArchiveInputStream archiveInputStream = new TarArchiveInputStream(compressedFileInputStream);
while ((currentFile = archiveInputStream.getNextEntry()) != null) {
for (String aFilenameWeAreSearchingFor : filenamesWeAreSearchingFor) {
if (currentFile.getName().endsWith(aFilenameWeAreSearchingFor)) {
LOG.debug("Found: " + currentFile.getName());
return copyFileToDisk(archiveInputStream, extractedToFilePath, aFilenameWeAreSearchingFor);
}
}
}
}
} finally {
compressedFileInputStream.close();
}
throw new ExpectedFileNotFoundException(
"Unable to find any expected filed for " + possibleFilenames.getBinaryTypeAsString());
}
private String untarFolder(InputStream compressedFileInputStream, String destinationFolder, List possibleFilenames) throws IOException {
String executablePath = "";
ArchiveEntry currentFile;
ArchiveInputStream archiveInputStream = new TarArchiveInputStream(compressedFileInputStream);
CloseShieldInputStream notClosableArchiveInputStream = new CloseShieldInputStream(archiveInputStream);
try {
while ((currentFile = archiveInputStream.getNextEntry()) != null) {
String name = currentFile.getName();
name = this.handlePathCreation(name, destinationFolder);
if (name.length() > 0) {
String extractedFile = copyFileToDisk(notClosableArchiveInputStream, destinationFolder, name);
for (String expectedFileName : possibleFilenames) {
if (extractedFile.endsWith(expectedFileName)) {
executablePath = extractedFile;
}
}
}
}
} finally {
compressedFileInputStream.close();
notClosableArchiveInputStream.close();
}
return executablePath;
}
private String unzipFolder(ZipFile zipFile, String destinationFolder, List possibleFilenames) {
String executablePath = "";
try {
Enumeration entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry zipEntry = entries.nextElement();
String name = zipEntry.getName();
name = this.handlePathCreation(name, destinationFolder);
if (name.length() > 0) {
String extractedFile = copyFileToDisk(zipFile.getInputStream(zipEntry), destinationFolder, name);
for (String expectedFileName : possibleFilenames) {
if (extractedFile.endsWith(expectedFileName)) {
executablePath = extractedFile;
}
}
}
}
} catch (IOException e) {
LOG.error("Unzip failed:" + e.getMessage());
} finally {
if (zipFile != null) {
try {
zipFile.close();
} catch (IOException e) {
LOG.error("Error closing zip file");
}
}
}
return executablePath;
}
/**
* Copy a file from an inputsteam to disk
*
* @param inputStream A valid input stream to read
* @param pathToExtractTo Path of the file we want to create
* @param filename Filename of the file we want to create
* @return Absolute path of the newly created file (Or existing file if overwriteFilesThatExist is set to false)
* @throws IOException IOException
*/
private String copyFileToDisk(InputStream inputStream, String pathToExtractTo, String filename) throws IOException {
if (!overwriteFilesThatExist) {
File[] existingFiles = new File(pathToExtractTo).listFiles();
if (null != existingFiles && existingFiles.length > 0) {
for (File existingFile : existingFiles) {
String existingFilename = existingFile.getName();
if (existingFilename.equals(filename)) {
LOG.info("Binary '" + existingFilename + "' exists: true");
LOG.info("Using existing '" + existingFilename + " 'binary.");
return existingFile.getAbsolutePath();
}
}
}
}
File outputFile = new File(pathToExtractTo, filename);
try {
if (!outputFile.exists() && !outputFile.getParentFile().mkdirs() && !outputFile.createNewFile()) {
throw new IOException("Unable to create " + outputFile.getAbsolutePath());
}
LOG.info("Extracting binary '" + filename + "'...");
FileUtils.copyInputStreamToFile(inputStream, outputFile);
LOG.info("Binary copied to " + outputFile.getAbsolutePath());
if (!outputFile.setExecutable(true) && !outputFile.canExecute()) {
LOG.warn("Unable to set executable flag (+x) on " + filename);
}
} finally {
inputStream.close();
}
return outputFile.getAbsolutePath();
}
private String handlePathCreation(String name, String destinationFolder) {
name = name.replace('\\', '/');
File destinationFile = new File(destinationFolder, name);
if (name.endsWith("/")) {
if (!destinationFile.isDirectory() && !destinationFile.mkdirs()) {
LOG.error("Error creating temp directory:" + destinationFile.getPath());
}
return "";
} else {
// Create the the parent directory if it doesn't exist
File parentFolder = destinationFile.getParentFile();
if (!parentFolder.isDirectory()) {
if (!parentFolder.mkdirs()) {
LOG.error("Error creating temp directory:" + parentFolder.getPath());
}
}
return name;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy