/*==========================================================================*\
| $Id: ZipPackager.java,v 1.1 2010/03/02 18:38:53 aallowat Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2006-2009 Virginia Tech
|
| This file is part of Web-CAT Electronic Submitter.
|
| Web-CAT is free software; you can redistribute it and/or modify
| it under the terms of the GNU General Public License as published by
| the Free Software Foundation; either version 2 of the License, or
| (at your option) any later version.
|
| Web-CAT is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along
| with Web-CAT; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package org.webcat.submitter.internal.packagers;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.webcat.submitter.IPackager;
import org.webcat.submitter.ISubmittableItem;
import org.webcat.submitter.SubmittableItemKind;
import org.webcat.submitter.internal.utility.StreamUtils;
//--------------------------------------------------------------------------
/**
* A packager that collects the submittable items into a ZIP archive.
*
* @author Tony Allevato (Virginia Tech Computer Science)
* @author latest changes by: $Author: aallowat $
* @version $Revision: 1.1 $ $Date: 2010/03/02 18:38:53 $
*/
public class ZipPackager implements IPackager
{
//~ Methods ...............................................................
// ----------------------------------------------------------
/**
* @see IPackager#startPackage(OutputStream, Map)
*/
public void startPackage(OutputStream stream,
Map<String, String> parameters)
throws IOException
{
zipStream = new ZipOutputStream(stream);
}
// ----------------------------------------------------------
/**
* @see IPackager#addSubmittableItem(ISubmittableItem)
*/
public void addSubmittableItem(ISubmittableItem item) throws IOException
{
if (item.getKind() == SubmittableItemKind.FOLDER)
{
if (item.getFilename().length() > 0 &&
!item.getFilename().equals("/"))
{
ZipEntry entry = new ZipEntry(item.getFilename() + "/");
zipStream.putNextEntry(entry);
zipStream.closeEntry();
}
}
else if (item.getKind() == SubmittableItemKind.FILE)
{
InputStream itemStream = item.getStream();
// If we try to stream the file directly into the zip file
// without determining its size for the zip entry, the archive
// will not expand properly under OS X. Until we can fix this,
// we stream each file entirely into memory to compute its
// length, then stream the memory buffer out to the zip file.
ByteArrayOutputStream memStream = new ByteArrayOutputStream();
StreamUtils.copy(itemStream, memStream, buffer);
itemStream.close();
long length = memStream.size();
ZipEntry entry = new ZipEntry(item.getFilename());
entry.setSize(length);
zipStream.putNextEntry(entry);
ByteArrayInputStream memInputStream =
new ByteArrayInputStream(memStream.toByteArray());
StreamUtils.copy(memInputStream, zipStream, buffer);
zipStream.closeEntry();
}
}
// ----------------------------------------------------------
/**
* @see IPackager#endPackage()
*/
public void endPackage() throws IOException
{
zipStream.finish();
zipStream.flush();
}
//~ Static/instance variables .............................................
/* The size of the buffer to use during stream copying. */
private static final int BUFFER_SIZE = 65536;
/* The ZIP output stream to write the package to. */
private ZipOutputStream zipStream;
/* The buffer to use during stream copying. */
private byte[] buffer = new byte[BUFFER_SIZE];
}