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

com.github.skjolber.unzip.ZipFileEngine Maven / Gradle / Ivy

package com.github.skjolber.unzip;

import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

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

public class ZipFileEngine implements UncaughtExceptionHandler {

	protected FileEntryHandler handler;
	protected ThreadPoolExecutor executor;
	protected volatile Throwable uncaughtException = null;
	
	public ZipFileEngine(FileEntryHandler handler) {
		this(handler, Runtime.getRuntime().availableProcessors());
	}

	public ZipFileEngine(FileEntryHandler handler, int threads) {
		this(handler, (ThreadPoolExecutor) Executors.newFixedThreadPool(threads));
	}

	public ZipFileEngine(FileEntryHandler handler, ThreadPoolExecutor executor) {
		super();
		this.handler = handler;
		this.executor = executor;
	}

	public boolean handle(ZipFileSource source) throws IOException {
		return handle(source, null);
	}

	public boolean handle(ZipFileSource source, List files) throws IOException {
		AtomicInteger counter = new AtomicInteger();
		
		List targetFiles;
		if(files == null) {
			ZipFile zipFile = source.getZipFile();
			
			targetFiles = new ArrayList(64);
			
			Enumeration entriesInPhysicalOrder = zipFile.getEntriesInPhysicalOrder();
			while(entriesInPhysicalOrder.hasMoreElements()) {
				ZipArchiveEntry nextElement = entriesInPhysicalOrder.nextElement();
				targetFiles.add(nextElement.getName());
			}
			zipFile.close();
		} else {
			targetFiles = files;
		}
		
		// wrap exception handler to detect errors
		ThreadFactory threadFactory = executor.getThreadFactory();
		executor.setThreadFactory(new UncaughtExceptionHandlerThreadFactory(threadFactory, this));
		try {
			handler.beginFileCollection(null);
			for(int i = 0; i < executor.getMaximumPoolSize(); i++) {
				ZipFile z = source.getZipFile();
				executor.execute(new ZipFileProcessor(counter, targetFiles, z, handler, executor));
			}
			
			while (executor.getActiveCount() > 0 || !executor.getQueue().isEmpty()) {
				try {
					Thread.sleep(20);
				} catch (InterruptedException e) {
					break;
				}
	        }
			handler.endFileCollection(null, executor);
			
			while (executor.getActiveCount() > 0 || !executor.getQueue().isEmpty()) {
				try {
					Thread.sleep(20);
				} catch (InterruptedException e) {
					break;
				}
	        }
			
			return uncaughtException == null;
		} finally {
			executor.setThreadFactory(threadFactory);
		}
	}
	
	public void close() {
		executor.shutdown();
	}

	@Override
	public void uncaughtException(Thread t, Throwable e) {
		this.uncaughtException = e;
	}
	
	public void reset() {
		uncaughtException = null;
	}
	
	public Throwable getUncaughtException() {
		return uncaughtException;
	}
	
	public ThreadPoolExecutor getExecutor() {
		return executor;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy