/*******************************************************************************
* Copyright (c) 2008 Pierre-Antoine Grégoire.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre-Antoine Grégoire - initial API and implementation
*******************************************************************************/
package org.org.eclipse.core.utils.platform.tools;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.FileType;
import org.apache.commons.vfs.impl.DefaultFileSystemManager;
import org.apache.commons.vfs.impl.StandardFileSystemManager;
/**
* @author pagregoire
*/
public final class ArchivesToolBox {
public static interface IWriteHinter {
public WriteMode getFileWriteMode(File file);
public String alterFileName(File targetFolder, String fileName);
public String alterFolderName(File targetFolder, String folderName);
}
public enum WriteMode {
SKIP, REPLACE
}
private static class NoopFileWriteHinter implements IWriteHinter {
public WriteMode getFileWriteMode(File targetFile) {
return WriteMode.REPLACE;
}
public String alterFileName(File targetFolder, String fileName) {
return fileName;
}
public String alterFolderName(File targetFolder, String folderName) {
return folderName;
}
}
public static void decompressArchiveSubPartTo(File archiveFile, File targetFolder, String pathInArchive) throws IOException {
decompressArchiveSubPartTo(archiveFile, targetFolder, pathInArchive, new NoopFileWriteHinter());
}
public static void decompressArchiveSubPartTo(File archiveFile, File targetFolder, String pathInArchive, IWriteHinter writeHinter) throws IOException {
if (!targetFolder.exists()) {
throw new FileNotFoundException("Folder does not exist:" + targetFolder);
}
if (isZip(archiveFile) || isJar(archiveFile)) {
decompressZipTo(archiveFile, targetFolder, pathInArchive, writeHinter);
} else if (isTar(archiveFile)) {
if (isTgz(archiveFile)) {
decompressTgzTo(archiveFile, targetFolder, pathInArchive, writeHinter);
} else if (isTbz2(archiveFile)) {
decompressTbz2To(archiveFile, targetFolder, pathInArchive, writeHinter);
} else {
decompressTarTo(archiveFile, targetFolder, pathInArchive, writeHinter);
}
} else if (isGz(archiveFile)) {
decompressGzTo(archiveFile, targetFolder, pathInArchive, writeHinter);
} else if (isBz2(archiveFile)) {
decompressBz2To(archiveFile, targetFolder, pathInArchive, writeHinter);
}
}
public static void decompressArchiveTo(File archiveFile, File targetFolder) throws IOException {
decompressArchiveSubPartTo(archiveFile, targetFolder, "", new NoopFileWriteHinter());
}
public static void decompressArchiveTo(File archiveFile, File targetFolder, IWriteHinter writeHinter) throws IOException {
decompressArchiveSubPartTo(archiveFile, targetFolder, "", writeHinter);
}
public static void decompressBz2To(File archiveFile, File targetFolder, String pathInArchive) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "bz2:", "/" + pathInArchive);
}
public static void decompressBz2To(File archiveFile, File targetFolder, String pathInArchive, IWriteHinter writeHinter) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "bz2:", "/" + pathInArchive, writeHinter);
}
public static void decompressGzTo(File archiveFile, File targetFolder, String pathInArchive) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "gz:", "/" + pathInArchive);
}
public static void decompressGzTo(File archiveFile, File targetFolder, String pathInArchive, IWriteHinter writeHinter) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "gz:", "/" + pathInArchive, writeHinter);
}
public static void decompressJarTo(File archiveFile, File targetFolder, String pathInArchive) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "jar:", "!" + pathInArchive);
}
public static void decompressJarTo(File archiveFile, File targetFolder, String pathInArchive, IWriteHinter writeHinter) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "jar:", "!" + pathInArchive, writeHinter);
}
public static void decompressTarTo(File archiveFile, File targetFolder, String pathInArchive) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "tar:", "!" + pathInArchive);
}
public static void decompressTarTo(File archiveFile, File targetFolder, String pathInArchive, IWriteHinter writeHinter) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "tar:", "!" + pathInArchive, writeHinter);
}
public static void decompressTbz2To(File archiveFile, File targetFolder, String pathInArchive) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "tbz2:", "!" + pathInArchive);
}
public static void decompressTbz2To(File archiveFile, File targetFolder, String pathInArchive, IWriteHinter writeHinter) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "tbz2:", "!" + pathInArchive, writeHinter);
}
public static void decompressTgzTo(File archiveFile, File targetFolder, String pathInArchive) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "tgz:", "!" + pathInArchive);
}
public static void decompressTgzTo(File archiveFile, File targetFolder, String pathInArchive, IWriteHinter writeHinter) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "tgz:", "!" + pathInArchive, writeHinter);
}
public static void decompressZipTo(File archiveFile, File targetFolder, String pathInArchive) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "zip:", "!" + pathInArchive);
}
public static void decompressZipTo(File archiveFile, File targetFolder, String pathInArchive, IWriteHinter writeHinter) throws IOException {
decompressArchiveTo(archiveFile, targetFolder, "zip:", "!" + pathInArchive, writeHinter);
}
public static boolean isArchive(File file) {
return isZip(file) || isTar(file) || isGz(file) || isBz2(file) || isJar(file) || isTgz(file) || isTbz2(file);
}
public static boolean isBz2(File file) {
return isFileOpeneableAs(file, "bz2:", "");
}
public static boolean isGz(File file) {
return isFileOpeneableAs(file, "gz:", "");
}
public static boolean isJar(File file) {
return isFileOpeneableAs(file, "jar:", "");
}
public static boolean isTar(File file) {
return isFileOpeneableAs(file, "tar:", "");
}
public static boolean isTbz2(File file) {
return isFileOpeneableAs(file, "tbz2:", "");
}
public static boolean isTgz(File file) {
return isFileOpeneableAs(file, "tgz:", "");
}
public static boolean isZip(File file) {
return isFileOpeneableAs(file, "zip:", "");
}
private static FileObject createFileObject(FileSystemManager fileSystemManager, File file, String archiveProtocol, String pathInArchive) throws FileSystemException {
return fileSystemManager.resolveFile(archiveProtocol + "/" + file.getAbsolutePath() + pathInArchive);
}
private static DefaultFileSystemManager createFileSystemManager() throws FileSystemException {
DefaultFileSystemManager fileSystemManager = new StandardFileSystemManager();
fileSystemManager.init();
return fileSystemManager;
}
private static void decompressArchiveTo(File archiveFile, File targetFolder, String archiveProtocol, String pathInArchive) throws IOException {
DefaultFileSystemManager fileSystemManager = createFileSystemManager();
FileObject fileObject = createFileObject(fileSystemManager, archiveFile, archiveProtocol, pathInArchive);
decompressFileObjectTo(fileObject, targetFolder);
fileSystemManager.close();
}
private static void decompressArchiveTo(File archiveFile, File targetFolder, String archiveProtocol, String pathInArchive, IWriteHinter writeHinter) throws IOException {
DefaultFileSystemManager fileSystemManager = createFileSystemManager();
FileObject fileObject = createFileObject(fileSystemManager, archiveFile, archiveProtocol, pathInArchive);
decompressFileObjectTo(fileObject, targetFolder, writeHinter);
fileSystemManager.close();
}
private static void decompressFileObjectTo(FileObject fileObject, File targetFolder) throws IOException {
decompressFileObjectTo(fileObject, targetFolder, new NoopFileWriteHinter());
}
private static void decompressFileObjectTo(FileObject fileObject, File targetFolder, IWriteHinter writeHinter) throws IOException {
for (FileObject child : fileObject.getChildren()) {
String childName = child.getName().getBaseName();
FileType type = child.getType();
if (type.equals(FileType.FOLDER)) {
String folderName = writeHinter.alterFolderName(targetFolder, childName);
File folder = new File(targetFolder, folderName);
if (!folder.exists()) {
folder.mkdirs();
}
decompressFileObjectTo(child, folder,writeHinter);
}
if (type.equals(FileType.FILE)) {
String fileName = writeHinter.alterFileName(targetFolder, childName);
File newFile = new File(targetFolder, fileName);
newFile.createNewFile();
WriteMode writeMode = writeHinter.getFileWriteMode(newFile);
if (writeMode != WriteMode.SKIP) {
FileOutputStream fileOutputStream = new FileOutputStream(newFile);
InputStream inputStream = child.getContent().getInputStream();
try {
IOToolBox.inToOut(inputStream, fileOutputStream);
} finally {
inputStream.close();
fileOutputStream.close();
}
}
}
}
}
private static boolean isFileOpeneableAs(File file, String archiveProtocol, String pathInArchive) {
boolean result = true;
try {
createFileObject(createFileSystemManager(), file, archiveProtocol, pathInArchive);
} catch (FileSystemException e) {
result = false;
}
return result;
}
private ArchivesToolBox() {
}
}