/**
* Copyright 2013 Thomas Rausch
*
* 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 org.rauschig.jarchivelib;
import static org.rauschig.jarchivelib.CommonsStreamFactory.createCompressorInputStream;
import static org.rauschig.jarchivelib.CommonsStreamFactory.createCompressorOutputStream;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorInputStream;
import org.apache.commons.compress.compressors.CompressorOutputStream;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
/**
* Implementation of a compressor that uses {@link CompressorStreamFactory} to generate compressor streams by a given
* compressor name passed when creating the GenericCompressor. Thus, it can be used for all compression algorithms the
* {@code org.apache.commons.compress} library supports.
*/
class CommonsCompressor implements Compressor {
private final CompressionType compressionType;
CommonsCompressor(CompressionType type) {
this.compressionType = type;
}
public CompressionType getCompressionType() {
return compressionType;
}
@Override
public void compress(File source, File destination) throws IllegalArgumentException, IOException {
assertSource(source);
assertDestination(destination);
if (destination.isDirectory()) {
destination = new File(destination, getCompressedFilename(source));
}
CompressorOutputStream compressed = null;
BufferedInputStream input = null;
try {
input = new BufferedInputStream(new FileInputStream(source));
compressed = createCompressorOutputStream(this, destination);
IOUtils.copy(input, compressed);
} catch (CompressorException e) {
throw new IOException(e);
} finally {
IOUtils.closeQuietly(compressed);
IOUtils.closeQuietly(input);
}
}
@Override
public void decompress(File source, File destination) throws IOException {
assertSource(source);
assertDestination(destination);
if (destination.isDirectory()) {
destination = new File(destination, getDecompressedFilename(source));
}
CompressorInputStream compressed = null;
FileOutputStream output = null;
try {
compressed = createCompressorInputStream(getCompressionType(), source);
output = new FileOutputStream(destination);
IOUtils.copy(compressed, output);
} catch (CompressorException e) {
throw new IOException(e);
} finally {
IOUtils.closeQuietly(compressed);
IOUtils.closeQuietly(output);
}
}
@Override
public String getFilenameExtension() {
return getCompressionType().getDefaultFileExtension();
}
private String getCompressedFilename(File source) {
return source.getName() + getFilenameExtension();
}
private String getDecompressedFilename(File source) {
FileType fileType = FileType.get(source);
if (compressionType != fileType.getCompressionType()) {
throw new IllegalArgumentException(source + " is not of type " + compressionType);
}
return source.getName().substring(0, source.getName().length() - fileType.getSuffix().length());
}
private void assertSource(File source) throws IllegalArgumentException, FileNotFoundException {
if (source == null) {
throw new IllegalArgumentException("Source is null");
} else if (source.isDirectory()) {
throw new IllegalArgumentException("Source " + source + " is a directory.");
} else if (!source.exists()) {
throw new FileNotFoundException(source.getName());
} else if (!source.canRead()) {
throw new IllegalArgumentException("Can not read from source " + source);
}
}
private void assertDestination(File destination) {
if (destination == null) {
throw new IllegalArgumentException("Destination is null");
} else if (destination.isDirectory()) {
if (!destination.canWrite()) {
throw new IllegalArgumentException("Can not write to destination " + destination);
}
} else if (destination.exists() && !destination.canWrite()) {
throw new IllegalArgumentException("Can not write to destination " + destination);
}
}
}