Java tutorial
/* Copyright (C) 2005-2007 Jamie Angus Band * MailArchiva Open Source Edition Copyright (c) 2005-2007 Jamie Angus Band * This program 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. * * This program 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 this program; * if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * MessageStorage.java - stores messages on the file system * @author Jamie Band * @version 1.0 */ package com.stimulus.archiva.store; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import com.stimulus.archiva.domain.*; import com.stimulus.archiva.exception.MessageStoreException; import com.stimulus.archiva.exception.ProcessException; import com.stimulus.util.*; import java.io.*; import java.util.Date; import java.util.Locale; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import javax.mail.MessagingException; import javax.mail.Part; import org.apache.commons.logging.*; import java.util.*; import javax.crypto.*; import javax.crypto.spec.*; import java.security.spec.*; import javax.mail.internet.*; import javax.mail.*; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.security.*; import com.sun.mail.util.*; import com.stimulus.archiva.domain.Archiver; import com.stimulus.archiva.domain.Volume.SizeCounter; import com.stimulus.archiva.exception.*; public class MessageStore extends Archiver implements Serializable { private static final long serialVersionUID = -2610982280435598267L; protected static final Log logger = LogFactory.getLog(MessageStore.class.getName()); protected static final String messageFileExtension = ".mrc"; protected static final String attachmentFileExtension = ".att"; protected static final int FILE_SIZE = 0; protected static final int FILE_COUNT = 1; protected SecretKey key; protected AlgorithmParameterSpec paramSpec; protected TempFiles tempfiles; static enum Action { STRIP, COMBINE }; public MessageStore() { } public void init() throws MessageStoreException { tempfiles = Config.getFileSystem().getTempFiles(); byte[] salt = Config.getConfig().getSalt(); String passPhrase = getPassPhrase(); if (!isDefaultPassPhraseModified()) logger.warn("archiving is disabled. encryption password is not set."); int iterationCount = 17; String algorithm = Config.getConfig().getPBEAlgorithm(); // "PBEWithMD5AndDES") // Create the key try { KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount); key = SecretKeyFactory.getInstance(algorithm).generateSecret(keySpec); paramSpec = new PBEParameterSpec(salt, iterationCount); } catch (java.security.NoSuchAlgorithmException e) { throw new MessageStoreException( "failed to locate desired encryption algorithm {algorithm='" + algorithm + "'", logger); } catch (Exception e) { throw new MessageStoreException(e.toString(), e, logger); } } protected File getFileFromHashValue(Volume volume, String hash, String extension) { String filename = volume.getPath() + File.separatorChar + hash.substring(0, 3) + File.separator + hash.substring(3, 6) + File.separator + hash + extension; logger.debug("getMessageFileName() { return='" + filename + "'"); return new File(filename); } protected File getLegacyFileFromHashValue(Volume volume, String hash, int directoryLength, String extension) { // legacy String filename = volume.getPath() + File.separatorChar + hash.substring(0, directoryLength) + File.separator + hash + extension; logger.debug("getMessageFileName() { return='" + filename + "'"); return new File(filename); } public File getExistingFile(Volume volume, String hash, String extension) throws MessageStoreException { File file = getFileFromHashValue(volume, hash, extension); if (!file.exists()) { logger.debug("read file does not exist {file='" + file.getAbsolutePath() + "'}"); file = getLegacyFileFromHashValue(volume, hash, 8, extension); if (!file.exists()) { logger.debug("read file does not exist {file='" + file.getAbsolutePath() + "'}"); file = getLegacyFileFromHashValue(volume, hash, 3, extension); if (!file.exists()) { logger.debug("read file does not exist {file='" + file.getAbsolutePath() + "'}"); file = getLegacyFileFromHashValue(volume, hash, 6, extension); if (!file.exists()) { logger.debug("read file does not exist {file='" + file.getAbsolutePath() + "'}"); file = getLegacyFileFromHashValue(volume, hash, 4, extension); if (!file.exists()) { return getFileFromHashValue(volume, hash, extension); } } } } } logger.debug("getMessageFileName() {return='" + file.getAbsolutePath() + "'}"); return file; } public File getNewFile(Volume volume, String hash, String extension) throws MessageStoreException { prepareStore(volume); createDirectories(volume, hash); File file = getFileFromHashValue(volume, hash, extension); logger.debug("getFile() {return='" + file.getAbsolutePath() + "'}"); return file; } /** * Retrieve the file location of a message that could not be indexed * @param emailID The email ID * @return The file location message not processed */ protected File getNoIndexFile(EmailID emailID) throws MessageStoreException { if (emailID == null || emailID.getUniqueID() == null) throw new MessageStoreException("assertion failure: null emailID or uniqueId", logger); String filename = Config.getFileSystem().getNoIndexPath() + File.separatorChar + emailID.getUniqueID() + messageFileExtension; logger.debug("getNoIndexFileName() {return='" + filename + "'}"); return new File(filename); } protected File getNoArchiveFile() throws MessageStoreException { String file = UUID.randomUUID().toString() + ".eml"; logger.debug("getNoArchiveFile() {return='" + file + "'}"); return new File(Config.getFileSystem().getNoArchivePath() + File.separatorChar + file); } /** * Create the directory where a volume is stored * @param volume The volume * @return The directory */ public void prepareStore(Volume volume) throws MessageStoreException { if (volume == null) throw new MessageStoreException("assertion failure: null volume", logger); logger.debug("createMessageStoreDir() {" + volume + "}"); File storeDir = new File(volume.getPath()); if (!storeDir.exists()) { logger.info("message store directory does not exist {" + volume + "}"); boolean success = storeDir.mkdirs(); if (!success) throw new MessageStoreException("failed to create message store directory {" + volume + "}", logger); logger.info("created message store directory {" + volume + "}"); } } /** * Create the directory where a message is stored * @param emailID The email ID * @return The message directory */ private void createDir(String directory) throws MessageStoreException { logger.debug("createDir() {messageDir='" + directory + "'}"); File todayDir = new File(directory); if (!todayDir.exists()) { logger.debug("message sub-directory does not exist {dir='" + directory + "'}"); boolean makedir = todayDir.mkdirs(); if (makedir) logger.debug("created message sub-directory {dir='" + directory + "'}"); else { if (!todayDir.exists()) throw new MessageStoreException("failed to create directory {dir='" + directory + "'}", logger); } } else { logger.debug("directory exists {dir='" + directory + "'}"); } } protected String createDirectories(Volume volume, String hashValue) throws MessageStoreException { String messageDirLevel1 = volume.getPath() + File.separatorChar + hashValue.substring(0, 3); createDir(messageDirLevel1); String messageDirLevel2 = messageDirLevel1 + File.separatorChar + hashValue.substring(3, 6); createDir(messageDirLevel2); logger.debug("createDirectories() {messageDir='" + messageDirLevel2 + "'}"); return messageDirLevel2; } /** * Insert a new message in the store * @param emailID The email ID * @param in The message contents * @param compress Is message compressed * @param encrypt Should encrypt message */ public boolean insertMessage(Email email) throws MessageStoreException { EmailID emailId = email.getEmailId(); logger.debug("insertMessage {" + emailId + "}"); if (emailId == null) { logger.fatal("assertion failure. emailId is null"); return false; } if (emailId.getVolume() == null) { logger.fatal("assertion failure. volume is null"); return false; } if (!isDefaultPassPhraseModified()) throw new MessageStoreException( "failed to archive message. encryption password is not set. {" + emailId + "}", logger); File messageFile = getNewFile(emailId.getVolume(), emailId.getUniqueID(), messageFileExtension); if (messageFile.exists()) { logger.debug("no need to archive. message already exists in the store. {" + emailId + "}"); return false; } try { email.setHeader("X-MailArchiva-Archive-Date", DateUtil.convertDatetoString(new Date())); } catch (MessagingException me) { logger.error("failed to set archive date"); } try { writeEmail(email, messageFile, true, true); Volume volume = email.getEmailId().getVolume(); if (volume != null && volume.isDiskSpaceChecked()) { updateDiskSpace(volume, messageFile.length()); } } catch (Throwable e) { messageFile.delete(); } return true; } /** * Retrieves a unique file identifier for a message * @param emailID The email ID */ protected String getUniqueIdFromFileName(String fileName) { int lastIndex = fileName.lastIndexOf('.'); String uid; if (lastIndex == -1) uid = ""; else uid = fileName.substring(0, lastIndex); logger.debug("getUniqueIdFromFileName {ret='" + uid + "'}"); return uid; } public boolean isMessageExist(EmailID emailID) { try { File messageFile = getExistingFile(emailID.getVolume(), emailID.getUniqueID(), messageFileExtension); return messageFile.exists(); } catch (Exception e) { return false; } } /** * Retrieve a message from the store * @param emailID The email ID * @param decompress Should decompress message * @param decrypt Should dencrypt message * @param headersOnly Should return just headers * @return An email message */ public Email retrieveMessage(EmailID emailID) throws MessageStoreException { if (emailID == null || emailID.getVolume() == null || emailID.getUniqueID() == null) throw new MessageStoreException("assertion failure: null emailID, volume or uniqueId", logger); logger.debug("retrieveMessage() {" + emailID + "'}"); Email message = null; try { File messageFile = getExistingFile(emailID.getVolume(), emailID.getUniqueID(), messageFileExtension); logger.debug("returning input stream {filename='" + messageFile + "'}"); message = new Email(emailID, getRawMessageInputStream(messageFile, true, true)); logger.debug("retrieved message {" + message + "}"); } catch (java.io.FileNotFoundException fnfe) { throw new MessageStoreException("The message is currently not accessible on the storage device.", fnfe, logger); } catch (Throwable e) { throw new MessageStoreException("Retrieved message does not appear to be well formed.", e, logger, ChainedException.Level.DEBUG); } return message; } public void copyEmail(File source, File dest) throws MessageStoreException { logger.debug("copyEmail()"); FileChannel in = null, out = null; try { in = new FileInputStream(source).getChannel(); out = new FileOutputStream(dest).getChannel(); in.transferTo(0, in.size(), out); } catch (Exception e) { throw new MessageStoreException("failed to copy email {src='" + source + "=',dest='" + dest + "'", e, logger); } finally { if (in != null) try { in.close(); } catch (Exception e) { } ; if (out != null) try { out.close(); } catch (Exception e) { } ; } } public void backupMessage(File file) throws MessageStoreException { logger.debug("backupMessage()"); File noArchiveFile = getNoArchiveFile(); logger.warn("copying email to no archive queue {dest='" + noArchiveFile.getAbsolutePath() + "'}"); //Mod start Seolhwa.kim 2017-04-13 //boolean renamed = file.renameTo(noArchiveFile); boolean renamed; try { Files.move(Paths.get(file.getAbsolutePath()), Paths.get(noArchiveFile.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING); renamed = true; } catch (IOException e) { // TODO Auto-generated catch block renamed = false; e.printStackTrace(); } //Mod End Seolhwa.kim 2017-04-13 if (!renamed) { throw new MessageStoreException("failed to copy message to noarchive queue", logger); } } public void backupMessage(Email email) throws MessageStoreException { logger.debug("backupMessage()"); File noArchiveFile = getNoArchiveFile(); logger.warn("copying email to no archive queue {dest='" + noArchiveFile.getAbsolutePath() + "'}"); FileOutputStream fos = null; try { fos = new FileOutputStream(noArchiveFile); email.writeTo(fos); } catch (Exception e) { throw new MessageStoreException("failed to copy message to noarchive queue:" + e.getMessage(), e, logger); } finally { try { fos.close(); } catch (Exception e) { } } } /** * Copy a message to a error directory if the message cannot be indexed * @param emailID The email ID */ public void backupMessage(EmailID emailID) throws MessageStoreException { if (emailID == null || emailID.getVolume() == null || emailID.getUniqueID() == null) throw new MessageStoreException("assertion failure: null emailID, volume or uniqueId", logger); logger.debug("backupMessage() {" + emailID + "'"); copyEmail(getExistingFile(emailID.getVolume(), emailID.getUniqueID(), messageFileExtension), getNoIndexFile(emailID)); } public void copyEmailToQuarantine(File sourceFile) throws MessageStoreException { logger.debug("copyEmailToQuarantine() {sourceFile='" + sourceFile + "'}"); copyEmail(sourceFile, getQuarantineFile(sourceFile.getName())); } public File getQuarantineFile(String filename) { return new File(Config.getFileSystem().getQuarantinePath() + File.separatorChar + filename); } public int getNoMessagesForRecovery() { File file = new File(Config.getFileSystem().getNoArchivePath()); if (file == null || !file.exists() || file.listFiles() == null) { logger.warn("getNoMessagesForRecovery() cannot access no archive directory. returning zero."); return 0; } return file.listFiles().length; } public class RecoverFileFilter implements FileFilter { RecoverMessage recover; int total = 0; int success = 0; int failed = 0; public RecoverFileFilter(RecoverMessage recover) { this.recover = recover; }; public boolean accept(File file) { Email message = null; try { logger.debug("retrieved inputstream {path='" + file.getPath() + "'}"); if (recover.recover(file)) { success++; logger.info("message has been rearchived {" + message + ", filepath='" + file.getPath() + "'}"); } else { failed++; logger.error("failed to rearchive message."); } } catch (Exception io) { logger.error("failed to recover message. {filename='" + file.getPath() + "'}", io); failed++; } return false; } public int getTotal() { return total; } public int getSuccess() { return success; } public int getFailed() { return failed; } public void end() { recover.end(failed, success, total); } } public void recoverMessages(RecoverMessage recover) throws MessageStoreException { recover.start(); String notarchiveddir = Config.getFileSystem().getNoArchivePath(); logger.debug("checking for failed messages that require rearchiving {notarchiveddirectory='" + notarchiveddir + "'}"); File noarchiveDir = new File(notarchiveddir); if (!noarchiveDir.exists()) { noarchiveDir.mkdir(); } if (!noarchiveDir.isDirectory()) { noarchiveDir.delete(); noarchiveDir.mkdir(); } RecoverFileFilter recoverFilter = new RecoverFileFilter(recover); noarchiveDir.listFiles(new RecoverFileFilter(recover)); recoverFilter.end(); } public int getNoQuarantinedMessages() { return new File(Config.getFileSystem().getQuarantinePath()).listFiles().length; } public void quarantineMessages() { String notarchiveddir = Config.getFileSystem().getNoArchivePath(); logger.debug("quarantineEmails {noarchivedpath='" + notarchiveddir + "'}"); File noarchiveDir = new File(notarchiveddir); if (!noarchiveDir.exists()) return; if (noarchiveDir.isDirectory()) { String[] children = noarchiveDir.list(); if (children.length > 0) logger.warn("there are messages that require rearchival {notarchiveddirectory='" + notarchiveddir + "'}"); for (int i = 0; i < children.length; i++) { String filepath = notarchiveddir + File.separatorChar + children[i]; logger.debug("attempting to quarantine file {path='" + filepath + "'}"); try { copyEmailToQuarantine(new File(filepath)); } catch (Exception e) { logger.error("failed to quarantine email (filepath='" + filepath + "'}", e); continue; } try { File delFile = new File(filepath); boolean deleted; deleted = delFile.delete(); File tmpfile = null; if (!deleted) //Mod start Seolhwa.kim 2017-04-13 //delFile.renameTo(File.createTempFile("oldrecovery", "tmp")); tmpfile = File.createTempFile("oldrecovery", "tmp"); try { Files.move(Paths.get(delFile.getAbsolutePath()), Paths.get(tmpfile.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //Mod end Seolhwa.kim 2017-04-13 delFile.deleteOnExit(); } catch (IOException io) { logger.error("failed to delete email {filepath='" + filepath + "'"); } } } } /** * Get a raw input stream for a message * @param emailID The email ID * @param decompress Should decompress message * @param decrypt Should decrypt message * @return An inputstream containing the message */ public InputStream getRawMessageInputStream(File messageFile, boolean decompress, boolean decrypt) throws IOException, MessageStoreException { if (messageFile == null) throw new MessageStoreException("assertion failure: null messageFileName", logger); InputStream is = new BufferedInputStream(new FileInputStream(messageFile)); Cipher dcipher = null; if (decrypt) { try { dcipher = Cipher.getInstance(key.getAlgorithm()); dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec); } catch (Exception e) { throw new MessageStoreException("failed to initialize cipher. cause:", e, logger); } is = new CipherInputStream(is, dcipher); } if (decompress) is = new GZIPInputStream(is); return is; } public InputStream getMessageInputStream(EmailID emailID) throws IOException, MessageStoreException { Email email = retrieveMessage(emailID); File file = File.createTempFile("raw", ".tmp"); tempfiles.markForDeletion(file); try { writeEmail(email, file, false, false); } catch (Exception e) { } return getRawMessageInputStream(file, false, false); } /** * Get a raw output stream for a message * @param messageFileName The file name of the message * @param compress Should compress message * @param encrypt Should encrypt message * @return An outputstream directed to the message */ public OutputStream getRawMessageOutputStream(File messageFile, boolean compress, boolean encrypt) throws IOException, MessageStoreException { if (messageFile == null) throw new MessageStoreException("assertion failure: null messageFileName", logger); OutputStream os = new BufferedOutputStream(new FileOutputStream(messageFile)); Cipher ecipher = null; if (encrypt) { try { ecipher = Cipher.getInstance(key.getAlgorithm()); ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); } catch (Exception e) { logger.fatal( "Please ensure you have the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files installed."); logger.fatal("Visit http://java.sun.com2/javase/downloads/index.jsp to download them."); throw new MessageStoreException("failed to initalize cipher. Cause:", e, logger); } os = new CipherOutputStream(os, ecipher); } if (compress) os = new GZIPOutputStream(os); return os; } /** * Generic handler for returning the status of the reindexing operation * @param ProcessMessage The process that must be executed */ public void processMessages(ProcessMessage process) throws ProcessException { if (process == null) throw new ProcessException("assertion failure: null procress", logger); logger.debug("start(). starting to process messages for indexing."); String storePath = process.workingVolume.getPath(); File storeDirectory = new File(storePath); if (storeDirectory != null && storeDirectory.isDirectory()) recurseMessages(storeDirectory, process); } public class MessageDirFilter implements FileFilter { ProcessMessage process; public MessageDirFilter(ProcessMessage process) { this.process = process; }; public boolean accept(File file) { if (file.isFile()) { if (file.getName().endsWith(messageFileExtension)) { logger.debug("unique file name:" + file.getName()); Email email = null; EmailID emailID = EmailID.getEmailID(process.workingVolume, getUniqueIdFromFileName(file.getName())); try { process.process(emailID); } catch (Exception e) { logger.error("failed to process message during re-indexing {" + emailID + "}", e); } catch (OutOfMemoryError ome) { logger.error("server has run out of memory. skipping message.", ome); } } } else { file.listFiles(this); } return false; } } private static long getFileOrDirectorySize(File file) { SizeCounter counter = new SizeCounter(); file.listFiles(counter); return counter.getTotal(); } protected void recurseMessages(File file, ProcessMessage process) throws ProcessException { MessageDirFilter messageDirFilter = new MessageDirFilter(process); file.listFiles(messageDirFilter); } public boolean findSignature(Object part) throws Exception { boolean foundSignature = false; if (part instanceof Multipart) { Multipart multipart = (Multipart) part; for (int i = 0, n = multipart.getCount(); i < n; i++) if (findSignature(multipart.getBodyPart(i))) foundSignature = true; } else if (part instanceof MimeMessage) { if (findSignature(((MimeMessage) part).getContent())) foundSignature = true; } else if (part instanceof MimeBodyPart) { MimeBodyPart mpb = (MimeBodyPart) part; String contentType = mpb.getContentType(); if (contentType.toLowerCase(Locale.ENGLISH).contains("multipart/signed")) foundSignature = true; } return foundSignature; } public void writeCorruptedEmail(MimeMessage message, File file) throws MessageStoreException { logger.debug("writeCorruptedEmail"); InputStream is = null; OutputStream os = null; try { logger.debug("writing corrupted email to quarantine {filename='" + file + "'}"); os = new BufferedOutputStream(new FileOutputStream(file)); is = message.getRawInputStream(); BufferedInputStream bis = new BufferedInputStream(is); int c = 0; while ((c = bis.read()) != -1) { os.write(c); } } catch (Throwable ex) { StreamUtil.emptyStream(is); throw new MessageStoreException("failed to write corrupted email to quarantine:" + ex.getMessage(), ex, logger); } finally { try { if (os != null) os.close(); if (is != null) is.close(); } catch (Exception e) { } } } public void saveEmailChanges(MimeMessage message) throws MessagingException { logger.debug("saveEmailChanges"); String[] messageId = message.getHeader("Message-Id"); //try { System.out.println("Content:"+message.getContent()); } catch (Exception e) {} message.saveChanges(); if (messageId != null && messageId.length > 0) message.setHeader("Message-Id", messageId[0]); } public String getHeader(MimeBodyPart mbp, String name) throws MessagingException { String header[] = mbp.getHeader(name); if (header != null && header.length > 0) return header[0]; else return null; } public File getExistingAttachmentFilePath(Volume volume, String hash) throws MessageStoreException { logger.debug("getAttachmentFilePath() {" + volume + ",hash='" + hash + "'}"); File attachFile = getFileFromHashValue(volume, hash, attachmentFileExtension); if (!attachFile.exists()) { attachFile = getLegacyFileFromHashValue(volume, hash, 3, attachmentFileExtension); if (!attachFile.exists()) { throw new MessageStoreException( "attachment does not exist {attachFile='" + attachFile.getAbsolutePath() + "'}", logger, ChainedException.Level.DEBUG); } } return attachFile; } public static void copy(File source, File dest) throws IOException { FileChannel in = null, out = null; try { in = new FileInputStream(source).getChannel(); out = new FileOutputStream(dest).getChannel(); long size = in.size(); MappedByteBuffer buf = in.map(FileChannel.MapMode.READ_ONLY, 0, size); out.write(buf); } finally { if (in != null) in.close(); if (out != null) out.close(); } } protected void updateDiskSpace(Volume volume, long fileLength) { // we have written to the drive, update disk space counters long indexChange = (long) (fileLength * 0.1); // rough approximation index %1 size store logger.debug("inc volume store disk space {storeinc='" + fileLength + "',indexinc='" + indexChange + "'}"); volume.incUsedSpace(indexChange, fileLength); } public byte[] writeEmail(Email message, File file, boolean compress, boolean encrypt) throws MessageStoreException { logger.debug("writeEmail"); OutputStream fos = null; try { MessageDigest sha = MessageDigest.getInstance("SHA-1"); fos = getRawMessageOutputStream(file, compress, encrypt); DigestOutputStream dos = new DigestOutputStream(fos, sha); message.writeTo(dos); byte[] digest = sha.digest(); if (digest == null) { throw new MessageStoreException("failed to generate email digest. digest is null.", logger, ChainedException.Level.DEBUG); } return digest; } catch (Exception e) { if (file.exists()) { boolean deleted = file.delete(); if (!deleted) { try { //Mod Start Seolhwa.kim 2017-04-13 //file.renameTo(File.createTempFile("ma", "tmp")); File tmpfile = File.createTempFile("ma", "tmp"); Files.move(Paths.get(file.getAbsolutePath()), Paths.get(tmpfile.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING); //Mod End Seolhwa.kim 2017-04-13 Config.getFileSystem().getTempFiles().markForDeletion(file); } catch (Exception e3) { } } } throw new MessageStoreException("failed to write email {filename='" + file.getAbsolutePath() + "'", e, logger); } finally { try { if (fos != null) fos.close(); } catch (Exception e) { logger.error("failed to close email file:" + e.getMessage()); } } /* try { //System.out.println("WRITEMAIL:"+message.getContent()+"XXXXXXXXXXXXXXXXXXXXXX"); FileOutputStream fos2 = new FileOutputStream("c:\\test.eml"); message.writeTo(fos2); fos2.close(); } catch (Exception e) { e.printStackTrace(); logger.error(e); }*/ } public void writeTo(MimePart part, OutputStream os, String[] includeList) throws IOException, MessagingException { LineOutputStream los = null; if (os instanceof LineOutputStream) { los = (LineOutputStream) os; } else { los = new LineOutputStream(os); } Enumeration hdrLines = part.getMatchingHeaderLines(includeList); while (hdrLines.hasMoreElements()) { String line = (String) hdrLines.nextElement(); los.writeln(line); } los.writeln(); os = MimeUtility.encode(os, part.getEncoding()); part.getDataHandler().writeTo(os); os.flush(); } }