All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netarchivesuite.heritrix3wrapper.unzip.UnzipUtils Maven / Gradle / Ivy

There is a newer version: 1.0.3
Show newest version
package org.netarchivesuite.heritrix3wrapper.unzip;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;

public class UnzipUtils {

    /** Size of the buffer to read/write data. */
    private static final int BUFFER_SIZE = 8192;

    // Not thread-safe!
    private static byte[] tmpBuffer = new byte[BUFFER_SIZE];

    public static void unzip(String zipFilePath, String dstDirStr) throws IOException {
        unzip(zipFilePath, 0, dstDirStr);
    }

    public static void unzip(String zipFilePath, int trimLevel, String dstDirStr) throws IOException {
        File dstDir = new File(dstDirStr);
        if (!dstDir.exists()) {
            dstDir.mkdir();
        }
        List fileModeDateBacklog = new LinkedList();
        FileModeDate fileModeDate;
        ZipFile zipFile = new ZipFile(zipFilePath);
        Enumeration entries = zipFile.getEntries();
        ZipArchiveEntry entry;
        String name;
        InputStream in;
        boolean bInclude = (trimLevel == 0);
        while (entries.hasMoreElements()) {
            entry = entries.nextElement();
            name = entry.getName();
            if (trimLevel > 0) {
            	int trim = trimLevel;
            	int pos = 0;
            	while (trim > 0 && pos != -1) {
            		pos = findPathSeparator(name, pos);
            		if (pos > 0) {
            			++pos;
            			--trim;
            		}
            	}
            	if (trim == 0) {
            		name = name.substring(pos);
            		bInclude = true;
            	} else {
            		bInclude = false;
            	}
            }
            if (bInclude) {
                File dstFile = new File(dstDir, name);
                long lastModified = entry.getTime();
                if (entry.isDirectory()) {
                    dstFile.mkdir();
                    fileModeDate = new FileModeDate();
                    fileModeDate.name = name;
                    fileModeDate.file = dstFile;
                    if (entry.getPlatform() == ZipArchiveEntry.PLATFORM_UNIX) {
                        fileModeDate.perms = unixModeToPosixSet(entry.getUnixMode());
                    }
                    if (lastModified != -1) {
                        fileModeDate.lastModified = lastModified;
                    }
                    fileModeDateBacklog.add(fileModeDate);
                } else if (entry.isUnixSymlink()) {
                } else {
                    in = zipFile.getInputStream(entry);
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dstFile));
                    int read = 0;
                    while ((read = in.read(tmpBuffer)) != -1) {
                        bos.write(tmpBuffer, 0, read);
                    }
                    bos.close();
                    in.close();
                    if (entry.getPlatform() == ZipArchiveEntry.PLATFORM_UNIX) {
                        int unixMode = entry.getUnixMode();
                        Set perms = unixModeToPosixSet(unixMode);
                        Files.setPosixFilePermissions(dstFile.toPath(), perms);
                        //System.out.println(String.format("%o", unixMode) + " " + entry.getName());
                    }
                    if (lastModified != -1) {
                        dstFile.setLastModified(entry.getTime());
                    }
                }
            }
        }
        zipFile.close();
        Collections.sort(fileModeDateBacklog, new Comparator() {
            @Override
            public int compare(FileModeDate o1, FileModeDate o2) {
                return o2.name.length() - o1.name.length();
            }});
        Iterator iter = fileModeDateBacklog.iterator();
        while (iter.hasNext()) {
            fileModeDate = iter.next();
            if (fileModeDate.perms != null) {
                Files.setPosixFilePermissions(fileModeDate.file.toPath(), fileModeDate.perms);
            }
            if (fileModeDate.lastModified != -1) {
                fileModeDate.file.setLastModified(fileModeDate.lastModified);
            }
        }
    }

    public static class FileModeDate {
        public String name;
        public File file;
        public Set perms = null;
        public long lastModified = -1;
    }

    public static PosixFilePermission[] posixFilePermissionsBitSorted = {
        PosixFilePermission.OTHERS_EXECUTE,
        PosixFilePermission.OTHERS_WRITE,
        PosixFilePermission.OTHERS_READ,
        PosixFilePermission.GROUP_EXECUTE,
        PosixFilePermission.GROUP_WRITE,
        PosixFilePermission.GROUP_READ,
        PosixFilePermission.OWNER_EXECUTE,
        PosixFilePermission.OWNER_WRITE,
        PosixFilePermission.OWNER_READ
    };

    public static Set unixModeToPosixSet(int unixMode) {
        Set permissions = new TreeSet();
        int bit = 8;
        //StringBuilder sb = new StringBuilder();
        while (bit >= 0) {
            if ((unixMode & (1 << bit)) != 0) {
                permissions.add(posixFilePermissionsBitSorted[bit]);
                //sb.append("1");
            } else {
                //sb.append("0");
            }
            --bit;
        }
        //System.out.println(sb.toString());
        return permissions;
    }

    public static int findPathSeparator(String str, int from) {
    	int pos = -1;
    	int len = str.length();
    	int c;
    	while (pos == -1 && from < len) {
    		c = str.charAt( from );
    		if (c == '/' || c == '\\') {
    			pos = from;
    		} else {
    			++from;
    		}
    	}
    	return pos;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy