blob: 58407150f3b6f88a6aebb134207c147e4230eeeb [file] [log] [blame]
package org.eclipse.jdt.internal.ui.jarexporter;
/*
* Licensed Materials - Property of IBM,
* WebSphere Studio Workbench
* (c) Copyright IBM Corp 2000
*/
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
/**
* Exports resources to a .zip file
*/
/*package*/
class ZipFileExporter {
private ZipOutputStream outputStream;
private StringBuffer manifestContents;
private boolean generateManifestFile= false;
private boolean useCompression= true;
// constants
private static final String newline= "\r\n"; // is this platform dependent?
private static final String manifestMagic= "Manifest-Version: 1.0" + newline + newline;
private static final String nameLabel= "Name: ";
private static final String digestsLabel= "Digest-Algorithms: SHA MD5" + newline;
private static final String shaLabel= "SHA-Digest: ";
private static final String md5Label= "MD5-Digest: ";
private static final String manifestPath= "meta-inf/Manifest.mf";
/**
* Create an instance of this class.
*
* @param filename java.lang.String
* @param compress boolean
* @param includeManifestFile boolean
* @exception java.io.IOException
*/
public ZipFileExporter(String filename, boolean compress, boolean includeManifestFile) throws IOException {
outputStream= new ZipOutputStream(new FileOutputStream(filename));
useCompression= compress;
generateManifestFile= includeManifestFile;
if (generateManifestFile)
manifestContents= new StringBuffer(manifestMagic);
}
/**
* Create a new entry in the manifest file being constructed.
*
* @param pathname java.lang.String
* @param file org.eclipse.core.resources.IFile
* @exception java.io.IOException
* @exception org.eclipse.core.runtime.CoreException
*/
protected void appendToManifest(String pathname, IFile file) throws IOException, CoreException {
StringBuffer manifestEntry= new StringBuffer();
manifestEntry.append(nameLabel);
manifestEntry.append(pathname);
manifestEntry.append(newline);
manifestEntry.append(digestsLabel);
manifestEntry.append(shaLabel);
byte[] fileContents= null;
// we don't have to EnsureLocal because it was already done in #write
InputStream contentStream= file.getContents(false);
Reader in= new InputStreamReader(contentStream);
int chunkSize= contentStream.available();
StringBuffer buffer= new StringBuffer(chunkSize);
char[] readBuffer= new char[chunkSize];
int n= in.read(readBuffer);
while (n > 0) {
buffer.append(readBuffer);
n= in.read(readBuffer);
}
contentStream.close();
fileContents= buffer.toString().getBytes();
try {
byte[] hashValue= MessageDigest.getInstance("SHA").digest(fileContents);
manifestEntry.append(Base64Encoder.encode(hashValue));
manifestEntry.append(newline);
manifestEntry.append(md5Label);
hashValue= MessageDigest.getInstance("MD5").digest(fileContents);
manifestEntry.append(Base64Encoder.encode(hashValue));
manifestEntry.append(newline + newline);
} catch (NoSuchAlgorithmException e) {
// should never happen
return;
}
manifestContents.append(manifestEntry.toString());
}
/**
* Do all required cleanup now that we're finished with the
* currently-open .zip
*
* @exception java.io.IOException
*/
public void finished() throws IOException {
if (generateManifestFile)
writeManifestFile();
outputStream.close();
}
/**
* Write the passed resource to the current archive
*
* @param resource org.eclipse.core.resources.IFile
* @param destinationPath java.lang.String
* @exception java.io.IOException
* @exception org.eclipse.core.runtime.CoreException
*/
public void write(IFile resource, String destinationPath) throws IOException, CoreException {
ByteArrayOutputStream output= null;
InputStream contentStream= null;
try {
output= new ByteArrayOutputStream();
contentStream= resource.getContents(false);
int chunkSize= contentStream.available();
byte[] readBuffer= new byte[chunkSize];
int n= contentStream.read(readBuffer);
while (n > 0) {
output.write(readBuffer);
n= contentStream.read(readBuffer);
}
} finally {
if (output != null)
output.close();
if (contentStream != null)
contentStream.close();
}
write(destinationPath, output.toByteArray());
if (generateManifestFile)
appendToManifest(destinationPath, resource);
}
/**
* Create a new ZipEntry with the passed pathname and contents, and write it
* to the current archive
*
* @param pathname java.lang.String
* @param contents byte[]
* @exception java.io.IOException
*/
protected void write(String pathname, byte[] contents) throws IOException {
ZipEntry newEntry= new ZipEntry(pathname);
// if the contents are being compressed then we get the below for free.
if (!useCompression) {
newEntry.setMethod(ZipEntry.STORED);
newEntry.setSize(contents.length);
CRC32 checksumCalculator= new CRC32();
checksumCalculator.update(contents);
newEntry.setCrc(checksumCalculator.getValue());
}
outputStream.putNextEntry(newEntry);
outputStream.write(contents);
outputStream.closeEntry();
}
/**
* Write the constructed manifest.mf file to the current archive
*
* @exception java.io.IOException
*/
protected void writeManifestFile() throws IOException {
write(manifestPath, manifestContents.toString().getBytes());
}
}