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

net.derquinse.common.util.zip.ZipFileLoader Maven / Gradle / Ivy

Go to download

Module containing support classes depending on Java SE 6, Guava 11 and Joda-Time 2.0

There is a newer version: 1.0.37
Show newest version
/*
 * Copyright (C) the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.derquinse.common.util.zip;

import static com.google.common.base.Preconditions.checkArgument;
import static net.derquinse.common.util.zip.InternalPreconditions.checkInput;
import static net.derquinse.common.util.zip.InternalPreconditions.checkLoader;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import net.derquinse.common.io.MaximumSizeExceededException;
import net.derquinse.common.io.MemoryByteSource;
import net.derquinse.common.io.MemoryByteSourceLoader;

import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteSource;
import com.google.common.io.Closer;
import com.google.common.io.Files;
import com.google.common.primitives.Ints;

/**
 * Zip file loader.
 * @author Andres Rodriguez
 */
public final class ZipFileLoader {
	/** Default memory loader. */
	private static final MemoryByteSourceLoader DEFAULT_LOADER = MemoryByteSourceLoader.get().chunkSize(16384);
	/** Default file loader. */
	private static final ZipFileLoader DEFAULT = new ZipFileLoader(DEFAULT_LOADER, Long.MAX_VALUE);

	/** Loader to use. */
	private final MemoryByteSourceLoader loader;
	/** Maximum loaded size. */
	private final long maxSize;

	/** Returns a zip file loader with a default memory loader (heap, chunked, 16 KB chunks). */
	public static ZipFileLoader get() {
		return DEFAULT;
	}

	/** Constructor. */
	private ZipFileLoader(MemoryByteSourceLoader loader, long maxSize) {
		this.loader = checkLoader(loader);
		this.maxSize = maxSize;
	}

	/** Returns a zip file loader with the provided memory loader and the same maximum loaded size. */
	public ZipFileLoader loader(MemoryByteSourceLoader loader) {
		checkLoader(loader);
		if (loader.equals(this.loader)) {
			return this;
		}
		return new ZipFileLoader(loader, maxSize);
	}

	/** Returns a zip file loader with the same memory loader and the provided maximum loaded size. */
	public ZipFileLoader maxSize(long maxSize) {
		checkArgument(maxSize > 0, "The maximum loaded size must be greater than 0");
		if (maxSize == this.maxSize) {
			return this;
		}
		return new ZipFileLoader(loader, maxSize);
	}

	/**
	 * Loads a zip file into memory.
	 * @param input Input data. The stream is not closed.
	 * @return The loaded zip file.
	 * @throws IOException if an I/O error occurs.
	 * @throws MaximumSizeExceededException if any of the entries exceeds the maximum size.
	 */
	public LoadedZipFile load(InputStream input) throws IOException {
		checkInput(input);
		ImmutableMap.Builder b = ImmutableMap.builder();
		MemoryByteSourceLoader currentLoader = loader;
		long allowed = maxSize;
		final ZipInputStream zis = new ZipInputStream(input);
		ZipEntry entry;
		while ((entry = zis.getNextEntry()) != null) {
			if (allowed < currentLoader.getMaxSize()) {
				currentLoader = currentLoader.maxSize(Ints.saturatedCast(allowed));
			}
			try {
				final MemoryByteSource data = currentLoader.load(zis);
				allowed -= data.size();
				final String item = entry.getName();
				b.put(item, data);
			} catch (IllegalArgumentException e) {
				throw new IllegalArgumentException(String.format("Maximum size of %d exceeded while decompressing", maxSize));
			} finally {
				zis.closeEntry();
			}
		}
		return new LoadedZipFile(loader, b.build());
	}

	/**
	 * Loads a zip file into memory.
	 * @param input Input data.
	 * @return The loaded zip file.
	 * @throws IOException if an I/O error occurs
	 * @throws MaximumSizeExceededException if any of the entries exceeds the maximum size.
	 */
	public LoadedZipFile load(ByteSource input) throws IOException {
		checkInput(input);
		Closer closer = Closer.create();
		try {
			return load(closer.register(input.openStream()));
		} finally {
			closer.close();
		}
	}

	/**
	 * Loads a zip file into memory.
	 * @param file Input file.
	 * @return A map from zip entry nada to entry data.
	 * @throws IOException if an I/O error occurs
	 * @throws MaximumSizeExceededException if any of the entries exceeds the maximum size.
	 */
	public LoadedZipFile load(File file) throws IOException {
		checkInput(file);
		return load(Files.asByteSource(file));
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return Objects.hashCode(loader, maxSize);
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof ZipFileLoader) {
			ZipFileLoader other = (ZipFileLoader) obj;
			return maxSize == other.maxSize && loader.equals(other.loader);
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return Objects.toStringHelper(this).add("maxSize", maxSize).add("loader", loader).toString();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy