diff options
Diffstat (limited to 'mail/src/main/java/org/spongycastle/mail/smime/util/FileBackedMimeBodyPart.java')
-rw-r--r-- | mail/src/main/java/org/spongycastle/mail/smime/util/FileBackedMimeBodyPart.java | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/mail/src/main/java/org/spongycastle/mail/smime/util/FileBackedMimeBodyPart.java b/mail/src/main/java/org/spongycastle/mail/smime/util/FileBackedMimeBodyPart.java new file mode 100644 index 00000000..6bae91c9 --- /dev/null +++ b/mail/src/main/java/org/spongycastle/mail/smime/util/FileBackedMimeBodyPart.java @@ -0,0 +1,162 @@ +package org.bouncycastle.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(); + } + } |