/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.integration.regression;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import com.google.common.collect.Lists;
/**
* Implementation of RegressionIO which reads and writes a dump to a zip file.
*/
public abstract class ZipFileRegressionIO extends RegressionIO implements AutoCloseable {
public ZipFileRegressionIO(File zipFile, Format format) throws IOException {
super(zipFile, format);
}
protected String createObjectPath(final String type, String identifier) {
String objectPath = createFilename(identifier);
if (type != null) {
objectPath = type + "/" + objectPath;
}
return objectPath;
}
public static ZipFileRegressionIO createWriter(File zipFile, Format format) throws IOException {
return new WritingZipFileRegressionIO(zipFile, format);
}
public static ZipFileRegressionIO createReader(File zipFile, Format format) throws IOException {
return new ReadingZipFileRegressionIO(zipFile, format);
}
/**
* An implementation which only writes to zip files. Read operations throw
* {@link UnsupportedOperationException}s.
*/
private static final class WritingZipFileRegressionIO extends ZipFileRegressionIO {
/**
* The zip output stream - not null
*/
private ZipArchiveOutputStream _zipArchiveOS;
private WritingZipFileRegressionIO(File zipFile, Format format) throws IOException {
super(zipFile, format);
_zipArchiveOS = new ZipArchiveOutputStream(zipFile);
}
@Override
public void write(String type, Object o, String identifier) throws IOException {
ZipArchiveEntry entry = new ZipArchiveEntry(createObjectPath(type, identifier));
_zipArchiveOS.putArchiveEntry(entry);
getFormat().write(getFormatContext(), o, _zipArchiveOS);
_zipArchiveOS.flush();
_zipArchiveOS.closeArchiveEntry();
}
@Override
public void endWrite() throws IOException {
super.endWrite();
if (_zipArchiveOS != null) {
_zipArchiveOS.close();
}
}
@Override
public void close() throws Exception {
if (_zipArchiveOS != null) {
_zipArchiveOS.close();
}
}
private UnsupportedOperationException unimplemented() {
throw new UnsupportedOperationException("Cannot perform reads when in write mode.");
}
@Override
public Object read(String type, String identifier) throws IOException {
throw unimplemented();
}
@Override
public List<String> enumObjects(String type) throws IOException {
throw unimplemented();
}
}
/**
* An implementation which only reads from zip files. Write operations throw
* {@link UnsupportedOperationException}s.
*/
private static final class ReadingZipFileRegressionIO extends ZipFileRegressionIO {
/**
* The zip file. Not null.
*/
private ZipFile _zipFile;
public ReadingZipFileRegressionIO(File zipFile, Format format) throws IOException {
super(zipFile, format);
initZipFile(zipFile);
}
private void initZipFile(File zipFile) throws IOException {
if (!zipFile.exists()) {
throw new IllegalStateException("Unable to locate specified zip file on the file system: " + zipFile.getPath());
}
_zipFile = new ZipFile(zipFile);
}
@Override
public void close() throws Exception {
_zipFile.close();
}
@Override
public void write(String type, Object o, String identifier) throws IOException {
unimplemented();
}
private void unimplemented() {
throw new UnsupportedOperationException("Cannot perform writes when in read mode.");
}
@Override
public Object read(String type, String identifier) throws IOException {
String objectPath = createObjectPath(type, identifier);
ZipArchiveEntry entry = _zipFile.getEntry(objectPath);
if (entry == null) {
throw new IllegalArgumentException(objectPath + " does not exist in this archive.");
}
InputStream inputStream = _zipFile.getInputStream(entry);
return getFormat().read(getFormatContext(), inputStream);
}
@Override
public List<String> enumObjects(String type) throws IOException {
List<String> objectIdentifiers = Lists.newLinkedList();
Pattern typeNameFormat = Pattern.compile("(.*)/(.*)");
@SuppressWarnings("unchecked")
Enumeration<ZipArchiveEntry> entries = _zipFile.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry nextEntry = entries.nextElement();
String entryName = nextEntry.getName();
Matcher matcher = typeNameFormat.matcher(entryName);
if (matcher.matches()) {
String objectType = matcher.group(1);
if (objectType.equals(type)) {
String objectIdentifierFileName = matcher.group(2);
if (isIdentifierIncluded(objectIdentifierFileName)) {
String objectIdentifier = stripIdentifierExtension(objectIdentifierFileName);
objectIdentifiers.add(objectIdentifier);
}
}
}
}
return objectIdentifiers;
}
}
}