org.spongycastle.mail.smime.util.FileBackedMimeBodyPart Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scprov-jdk15 Show documentation
Show all versions of scprov-jdk15 Show documentation
Spongy Castle is a package-rename (org.bouncycastle.* to org.spongycastle.*) of Bouncy Castle intended for Android.
Android ships with a stripped-down version of Bouncy Castle - this causes classloader collisions if you try to add
an alternative (updated/complete) Bouncy Castle jar.
This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.5.
package org.spongycastle.mail.smime.util;
import javax.mail.MessagingException;
import javax.mail.internet.InternetHeaders;
import javax.mail.internet.MimeBodyPart;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
public class FileBackedMimeBodyPart
extends MimeBodyPart
{
private static final int BUF_SIZE = 32760;
private final File _file;
/**
* Create a MimeBodyPart backed by the data in file.
*
* @param file file containing the body part.
* @throws MessagingException an exception occurs parsing file.
* @throws IOException an exception occurs accessing file.
*/
public FileBackedMimeBodyPart(
File file)
throws MessagingException, IOException
{
super(new SharedFileInputStream(file));
_file = file;
}
/**
* Create a MimeBodyPart backed by file based on the headers and
* content data in content.
*
* @param content an inputstream containing the body part.
* @param file a handle to the backing file to use for storage.
* @throws MessagingException an exception occurs parsing the resulting body part in file.
* @throws IOException an exception occurs accessing file or content.
*/
public FileBackedMimeBodyPart(
InputStream content,
File file)
throws MessagingException, IOException
{
this(saveStreamToFile(content, file));
}
/**
* Create a MimeBodyPart backed by file, with the headers
* given in headers and body content taken from the stream body.
*
* @param headers headers for the body part.
* @param body internal content for the body part.
* @param file backing file to use.
*
* @throws MessagingException if the body part can't be produced.
* @throws IOException if there is an issue reading stream or writing to file.
*/
public FileBackedMimeBodyPart(
InternetHeaders headers,
InputStream body,
File file)
throws MessagingException, IOException
{
this(saveStreamToFile(headers, body, file));
}
public void writeTo(
OutputStream out)
throws IOException, MessagingException
{
if (!_file.exists())
{
throw new IOException("file " + _file.getCanonicalPath() + " no longer exists.");
}
super.writeTo(out);
}
/**
* Close off the underlying shared streams and remove the backing file.
*
* @throws IOException if streams cannot be closed or the file cannot be deleted.
*/
public void dispose()
throws IOException
{
((SharedFileInputStream)contentStream).getRoot().dispose();
if (_file.exists() && !_file.delete())
{
throw new IOException("deletion of underlying file <" + _file.getCanonicalPath() + "> failed.");
}
}
private static File saveStreamToFile(InputStream content, File tempFile)
throws IOException
{
saveContentToStream(new FileOutputStream(tempFile), content);
return tempFile;
}
private static File saveStreamToFile(InternetHeaders headers, InputStream content, File tempFile)
throws IOException
{
OutputStream out = new FileOutputStream(tempFile);
Enumeration en = headers.getAllHeaderLines();
while (en.hasMoreElements())
{
writeHeader(out, (String)en.nextElement());
}
writeSeperator(out);
saveContentToStream(out, content);
return tempFile;
}
private static void writeHeader(OutputStream out, String header)
throws IOException
{
for (int i = 0; i != header.length(); i++)
{
out.write(header.charAt(i));
}
writeSeperator(out);
}
private static void writeSeperator(OutputStream out)
throws IOException
{
out.write('\r');
out.write('\n');
}
private static void saveContentToStream(
OutputStream out,
InputStream content)
throws IOException
{
byte[] buf = new byte[BUF_SIZE];
int len;
while ((len = content.read(buf, 0, buf.length)) > 0)
{
out.write(buf, 0, len);
}
out.close();
content.close();
}
}