📄 mimemessagewrapper.java
字号:
/*********************************************************************** * Copyright (c) 2000-2004 The Apache Software Foundation. * * All rights reserved. * * ------------------------------------------------------------------- * * Licensed under the Apache License, Version 2.0 (the "License"); you * * may not use this file except in compliance with the License. You * * may obtain a copy of the License at: * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * * implied. See the License for the specific language governing * * permissions and limitations under the License. * ***********************************************************************/package org.apache.james.core;import javax.activation.DataHandler;import javax.mail.Address;import javax.mail.Flags;import javax.mail.Header;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Multipart;import javax.mail.Session;import javax.mail.internet.InternetAddress;import javax.mail.internet.InternetHeaders;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeUtility;import javax.mail.internet.NewsAddress;import java.io.BufferedWriter;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.IOException;import java.io.LineNumberReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.io.SequenceInputStream;import java.io.UnsupportedEncodingException;import java.text.ParseException;import java.util.ArrayList;import java.util.Date;import java.util.Enumeration;import org.apache.james.util.InternetPrintWriter;import org.apache.james.util.RFC2822Headers;import org.apache.james.util.RFC822DateFormat;import org.apache.avalon.framework.activity.Disposable;import org.apache.avalon.excalibur.io.IOUtil;/** * This object wraps a MimeMessage, only loading the underlying MimeMessage * object when needed. Also tracks if changes were made to reduce * unnecessary saves. */public class MimeMessageWrapper extends MimeMessage implements Disposable { /** * Can provide an input stream to the data */ MimeMessageSource source = null; /** * The Internet headers in memory */ MailHeaders headers = null; /** * The mime message in memory */ MimeMessage message = null; /** * Record whether a change was made to this message */ boolean modified = false; /** * How to format a mail date */ RFC822DateFormat mailDateFormat = new RFC822DateFormat(); /** * A constructor that instantiates a MimeMessageWrapper based on * a MimeMessageSource * * @param source the MimeMessageSource */ public MimeMessageWrapper(MimeMessageSource source) { super(Session.getDefaultInstance(System.getProperties(), null)); this.source = source; } /** * Returns the source ID of the MimeMessageSource that is supplying this * with data. * @see MimeMessageSource */ public String getSourceId() { return source.getSourceId(); } /** * Load the message headers from the internal source. * * @throws MessagingException if an error is encountered while * loading the headers */ private synchronized void loadHeaders() throws MessagingException { if (headers != null) { //Another thread has already loaded these headers return; } try { InputStream in = source.getInputStream(); try { headers = new MailHeaders(in); } finally { IOUtil.shutdownStream(in); } } catch (IOException ioe) { throw new MessagingException("Unable to parse headers from stream: " + ioe.getMessage(), ioe); } } /** * Load the complete MimeMessage from the internal source. * * @throws MessagingException if an error is encountered while * loading the message */ private synchronized void loadMessage() throws MessagingException { if (message != null) { //Another thread has already loaded this message return; } InputStream in = null; try { in = source.getInputStream(); headers = new MailHeaders(in); ByteArrayInputStream headersIn = new ByteArrayInputStream(headers.toByteArray()); in = new SequenceInputStream(headersIn, in); message = new MimeMessage(session, in); } catch (IOException ioe) { throw new MessagingException("Unable to parse stream: " + ioe.getMessage(), ioe); } finally { IOUtil.shutdownStream(in); } } /** * Internal implementation to get InternetAddress headers */ private Address[] getAddressHeader(String name) throws MessagingException { String addr = getHeader(name, ","); if (addr == null) { return null; } else { return InternetAddress.parse(addr); } } /** * Internal implementation to find headers */ private String getHeaderName(Message.RecipientType recipienttype) throws MessagingException { String s; if (recipienttype == Message.RecipientType.TO) { s = RFC2822Headers.TO; } else if (recipienttype == Message.RecipientType.CC) { s = RFC2822Headers.CC; } else if (recipienttype == Message.RecipientType.BCC) { s = RFC2822Headers.BCC; } else if (recipienttype == RecipientType.NEWSGROUPS) { s = "Newsgroups"; } else { throw new MessagingException("Invalid Recipient Type"); } return s; } /** * Get whether the message has been modified. * * @return whether the message has been modified */ public boolean isModified() { return modified; } /** * Rewritten for optimization purposes */ public void writeTo(OutputStream os) throws IOException, MessagingException { if (message == null || !isModified()) { // We do not want to instantiate the message... just read from source // and write to this outputstream InputStream in = source.getInputStream(); try { copyStream(in, os); } finally { IOUtil.shutdownStream(in); } } else { writeTo(os, os); } } /** * Rewritten for optimization purposes */ public void writeTo(OutputStream os, String[] ignoreList) throws IOException, MessagingException { writeTo(os, os, ignoreList); } /** * Write */ public void writeTo(OutputStream headerOs, OutputStream bodyOs) throws IOException, MessagingException { writeTo(headerOs, bodyOs, new String[0]); } public void writeTo(OutputStream headerOs, OutputStream bodyOs, String[] ignoreList) throws IOException, MessagingException { if (message == null || !isModified()) { //We do not want to instantiate the message... just read from source // and write to this outputstream //First handle the headers InputStream in = source.getInputStream(); try { InternetHeaders headers = new InternetHeaders(in); PrintWriter pos = new InternetPrintWriter(new BufferedWriter(new OutputStreamWriter(headerOs), 512), true); for (Enumeration e = headers.getNonMatchingHeaderLines(ignoreList); e.hasMoreElements(); ) { String header = (String)e.nextElement(); pos.println(header); } pos.println(); pos.flush(); copyStream(in, bodyOs); } finally { IOUtil.shutdownStream(in); } } else { writeTo(message, headerOs, bodyOs, ignoreList); } } /** * Convenience method to take any MimeMessage and write the headers and body to two * different output streams */ public static void writeTo(MimeMessage message, OutputStream headerOs, OutputStream bodyOs) throws IOException, MessagingException { writeTo(message, headerOs, bodyOs, null); } /** * Convenience method to take any MimeMessage and write the headers and body to two * different output streams, with an ignore list */ public static void writeTo(MimeMessage message, OutputStream headerOs, OutputStream bodyOs, String[] ignoreList) throws IOException, MessagingException { if (message instanceof MimeMessageWrapper) { MimeMessageWrapper wrapper = (MimeMessageWrapper)message; wrapper.writeTo(headerOs, bodyOs, ignoreList); } else { if(message.getMessageID() == null) { message.saveChanges(); } //Write the headers (minus ignored ones) Enumeration headers = message.getNonMatchingHeaderLines(ignoreList); PrintWriter hos = new InternetPrintWriter(new BufferedWriter(new OutputStreamWriter(headerOs), 512), true); while (headers.hasMoreElements()) { hos.println((String)headers.nextElement()); } // Print header/data separator hos.println(); hos.flush(); InputStream bis = null; OutputStream bos = null; // Write the body to the output stream /* try { bis = message.getRawInputStream(); bos = bodyOs; } catch(javax.mail.MessagingException me) { // we may get a "No content" exception // if that happens, try it the hard way // Why, you ask? In JavaMail v1.3, when you initially // create a message using MimeMessage APIs, there is no // raw content available. getInputStream() works, but // getRawInputStream() throws an exception. bos = MimeUtility.encode(bodyOs, message.getEncoding()); bis = message.getInputStream(); } */ try { // Get the message as a stream. This will encode // objects as necessary, and we have some input from // decoding an re-encoding the stream. I'd prefer the // raw stream, but see bos = MimeUtility.encode(bodyOs, message.getEncoding()); bis = message.getInputStream(); } catch(javax.activation.UnsupportedDataTypeException udte) { /* If we get an UnsupportedDataTypeException try using * the raw input stream as a "best attempt" at rendering * a message. * * WARNING: JavaMail v1.3 getRawInputStream() returns * INVALID (unchanged) content for a changed message. * getInputStream() works properly, but in this case * has failed due to a missing DataHandler. * * MimeMessage.getRawInputStream() may throw a "no * content" MessagingException. In JavaMail v1.3, when * you initially create a message using MimeMessage * APIs, there is no raw content available. * getInputStream() works, but getRawInputStream() * throws an exception. If we catch that exception, * throw the UDTE. It should mean that someone has * locally constructed a message part for which JavaMail * doesn't have a DataHandler. */ try { bis = message.getRawInputStream(); bos = bodyOs; } catch(javax.mail.MessagingException _) { throw udte; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -