📄 mimemessagewrapper.java
字号:
/**************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * * or more contributor license agreements. See the NOTICE file * * distributed with this work for additional information * * regarding copyright ownership. The ASF licenses this file * * to you 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 org.apache.avalon.framework.activity.Disposable;import org.apache.avalon.framework.container.ContainerUtil;import org.apache.james.util.InternetPrintWriter;import org.apache.james.util.io.IOUtil;import javax.activation.DataHandler;import javax.mail.MessagingException;import javax.mail.Session;import javax.mail.internet.InternetHeaders;import javax.mail.internet.MimeMessage;import javax.mail.util.SharedByteArrayInputStream;import java.io.BufferedWriter;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.LineNumberReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.util.Enumeration;/** * 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 */ protected MimeMessageSource source = null; /** * This is false until we parse the message */ protected boolean messageParsed = false; /** * This is false until we parse the message */ protected boolean headersModified = false; /** * This is false until we parse the message */ protected boolean bodyModified = false; /** * Keep a reference to the sourceIn so we can close it * only when we dispose the message. */ private InputStream sourceIn; private MimeMessageWrapper(Session session) throws MessagingException { super(session); this.headers = null; this.modified = false; this.headersModified = false; this.bodyModified = false; } /** * A constructor that instantiates a MimeMessageWrapper based on * a MimeMessageSource * * @param source the MimeMessageSource * @throws MessagingException */ public MimeMessageWrapper(Session session, MimeMessageSource source) throws MessagingException { this(session); this.source = source; } /** * A constructor that instantiates a MimeMessageWrapper based on * a MimeMessageSource * * @param source the MimeMessageSource * @throws MessagingException * @throws MessagingException */ public MimeMessageWrapper(MimeMessageSource source) throws MessagingException { this(Session.getDefaultInstance(System.getProperties()),source); } public MimeMessageWrapper(MimeMessage original) throws MessagingException { this(Session.getDefaultInstance(System.getProperties())); flags = original.getFlags(); // if the original is an unmodified MimeMessageWrapped we clone the headers and // take its source. /* Temporary commented out because of JAMES-474 if (original instanceof MimeMessageWrapper && !((MimeMessageWrapper) original).bodyModified) { source = ((MimeMessageWrapper) original).source; // this probably speed up things if (((MimeMessageWrapper) original).headers != null) { ByteArrayOutputStream temp = new ByteArrayOutputStream(); InternetHeaders ih = ((MimeMessageWrapper) original).headers; MimeMessageUtil.writeHeadersTo(ih.getAllHeaderLines(),temp); headers = createInternetHeaders(new ByteArrayInputStream(temp.toByteArray())); headersModified = ((MimeMessageWrapper) original).headersModified; } } */ if (source == null) { ByteArrayOutputStream bos; int size = original.getSize(); if (size > 0) bos = new ByteArrayOutputStream(size); else bos = new ByteArrayOutputStream(); try { original.writeTo(bos); bos.close(); SharedByteArrayInputStream bis = new SharedByteArrayInputStream(bos.toByteArray()); parse(bis); bis.close(); saved = true; } catch (IOException ex) { // should never happen, but just in case... throw new MessagingException("IOException while copying message", ex); } } } /** * Returns the source ID of the MimeMessageSource that is supplying this * with data. * @see MimeMessageSource */ public synchronized String getSourceId() { return source != null ? source.getSourceId() : null; } /** * Load the message headers from the internal source. * * @throws MessagingException if an error is encountered while * loading the headers */ protected synchronized void loadHeaders() throws MessagingException { if (headers != null) { //Another thread has already loaded these headers return; } else if (source != null) { try { InputStream in = source.getInputStream(); try { headers = createInternetHeaders(in); } finally { IOUtil.shutdownStream(in); } } catch (IOException ioe) { throw new MessagingException("Unable to parse headers from stream: " + ioe.getMessage(), ioe); } } else { throw new MessagingException("loadHeaders called for a message with no source, contentStream or stream"); } } /** * Load the complete MimeMessage from the internal source. * * @throws MessagingException if an error is encountered while * loading the message */ protected synchronized void loadMessage() throws MessagingException { if (messageParsed) { //Another thread has already loaded this message return; } else if (source != null) { sourceIn = null; try { sourceIn = source.getInputStream(); parse(sourceIn); // TODO is it ok? saved = true; } catch (IOException ioe) { IOUtil.shutdownStream(sourceIn); sourceIn = null; throw new MessagingException("Unable to parse stream: " + ioe.getMessage(), ioe); } } else { throw new MessagingException("loadHeaders called for an unparsed message with no source"); } } /** * Get whether the message has been modified. * * @return whether the message has been modified */ public synchronized boolean isModified() { return headersModified || bodyModified || modified; } /** * Rewritten for optimization purposes */ public synchronized void writeTo(OutputStream os) throws IOException, MessagingException { if (source != null && !isModified()) { // We do not want to instantiate the message... just read from source // and write to this outputstream InputStream in = source.getInputStream(); try { MimeMessageUtil.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 synchronized void writeTo(OutputStream headerOs, OutputStream bodyOs, String[] ignoreList) throws IOException, MessagingException { if (source != 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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -