Author: bago
Date: Sun May 14 08:10:45 2006
New Revision: 406350
URL: http://svn.apache.org/viewcvs?rev=406350&view=rev
Log:
Core mimemessage handling changes to remove random NPE: merged r404773-r404802
to 2.3 branch (JAMES-474)
Modified:
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageCopyOnWriteProxy.java
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageUtil.java
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageWrapper.java
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageCopyOnWriteProxyTest.java
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageTest.java
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageWrapperTest.java
Modified:
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageCopyOnWriteProxy.java
URL:
http://svn.apache.org/viewcvs/james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageCopyOnWriteProxy.java?rev=406350&r1=406349&r2=406350&view=diff
==============================================================================
---
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageCopyOnWriteProxy.java
(original)
+++
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageCopyOnWriteProxy.java
Sun May 14 08:10:45 2006
@@ -18,6 +18,7 @@
package org.apache.james.core;
import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.container.ContainerUtil;
import javax.activation.DataHandler;
import javax.mail.Address;
@@ -46,8 +47,10 @@
/**
* Used internally to track the reference count
+ * It is important that this is static otherwise it will keep a reference
to
+ * the parent object.
*/
- protected static class ReferenceCounter {
+ protected static class MessageReferenceTracker {
/**
* reference counter
@@ -55,24 +58,12 @@
private int referenceCount = 1;
/**
- * @param original
- * MimeMessageWrapper
- * @throws MessagingException
+ * The mime message in memory
*/
- public ReferenceCounter() throws MessagingException {
- this(0);
- }
+ private MimeMessage wrapped = null;
- /**
- * @param original
- * MimeMessage to wrap
- * @param writable
- * if true we can alter the message itself, otherwise copy
on
- * write it.
- * @throws MessagingException
- */
- public ReferenceCounter(int startCounter) throws MessagingException {
- referenceCount = startCounter;
+ public MessageReferenceTracker(MimeMessage ref) {
+ wrapped = ref;
}
protected synchronized void incrementReferenceCount() {
@@ -81,15 +72,23 @@
protected synchronized void decrementReferenceCount() {
referenceCount--;
+ if (referenceCount<=0) {
+ ContainerUtil.dispose(wrapped);
+ wrapped = null;
+ }
}
protected synchronized int getReferenceCount() {
return referenceCount;
}
+ public MimeMessage getWrapped() {
+ return wrapped;
}
- protected ReferenceCounter refCount;
+ }
+
+ protected MessageReferenceTracker refCount;
/**
* @param original
@@ -123,12 +122,10 @@
throws MessagingException {
super(Session.getDefaultInstance(System.getProperties(), null));
- this.wrapped = original;
- if (wrapped instanceof MimeMessageCopyOnWriteProxy) {
- refCount = ((MimeMessageCopyOnWriteProxy) wrapped).refCount;
- wrapped = ((MimeMessageCopyOnWriteProxy)
wrapped).getWrappedMessage();
+ if (original instanceof MimeMessageCopyOnWriteProxy) {
+ refCount = ((MimeMessageCopyOnWriteProxy) original).refCount;
} else {
- refCount = new ReferenceCounter();
+ refCount = new MessageReferenceTracker(original);
}
if (!writeable) {
@@ -138,31 +135,43 @@
/**
* Check the number of references over the MimeMessage and clone it if
- * needed.
+ * needed before returning the reference
*
* @throws MessagingException
* exception
*/
- protected void checkCopyOnWrite() throws MessagingException {
+ protected MimeMessage getWrappedMessageForWriting() throws
MessagingException {
synchronized (refCount) {
if (refCount.getReferenceCount() > 1) {
refCount.decrementReferenceCount();
- refCount = new ReferenceCounter(1);
- wrapped = new MimeMessageWrapper(wrapped);
+ refCount = new MessageReferenceTracker(new
MimeMessageWrapper(refCount.getWrapped()));
}
}
+ return refCount.getWrapped();
+ }
+
+ /**
+ * @return
+ */
+ public MimeMessage getWrappedMessage() {
+ return refCount.getWrapped();
}
/**
- * The mime message in memory
+ * @see org.apache.avalon.framework.activity.Disposable#dispose()
*/
- protected MimeMessage wrapped = null;
+ public synchronized void dispose() {
+ if (refCount != null) {
+ refCount.decrementReferenceCount();
+ refCount = null;
+ }
+ }
/**
* Rewritten for optimization purposes
*/
public void writeTo(OutputStream os) throws IOException,
MessagingException {
- wrapped.writeTo(os);
+ getWrappedMessage().writeTo(os);
}
/**
@@ -170,7 +179,7 @@
*/
public void writeTo(OutputStream os, String[] ignoreList)
throws IOException, MessagingException {
- wrapped.writeTo(os, ignoreList);
+ getWrappedMessage().writeTo(os, ignoreList);
}
/**
@@ -181,7 +190,7 @@
* @see javax.mail.Message#getFrom()
*/
public Address[] getFrom() throws MessagingException {
- return wrapped.getFrom();
+ return getWrappedMessage().getFrom();
}
/**
@@ -189,154 +198,154 @@
*/
public Address[] getRecipients(Message.RecipientType type)
throws MessagingException {
- return wrapped.getRecipients(type);
+ return getWrappedMessage().getRecipients(type);
}
/**
* @see javax.mail.Message#getAllRecipients()
*/
public Address[] getAllRecipients() throws MessagingException {
- return wrapped.getAllRecipients();
+ return getWrappedMessage().getAllRecipients();
}
/**
* @see javax.mail.Message#getReplyTo()
*/
public Address[] getReplyTo() throws MessagingException {
- return wrapped.getReplyTo();
+ return getWrappedMessage().getReplyTo();
}
/**
* @see javax.mail.Message#getSubject()
*/
public String getSubject() throws MessagingException {
- return wrapped.getSubject();
+ return getWrappedMessage().getSubject();
}
/**
* @see javax.mail.Message#getSentDate()
*/
public Date getSentDate() throws MessagingException {
- return wrapped.getSentDate();
+ return getWrappedMessage().getSentDate();
}
/**
* @see javax.mail.Message#getReceivedDate()
*/
public Date getReceivedDate() throws MessagingException {
- return wrapped.getReceivedDate();
+ return getWrappedMessage().getReceivedDate();
}
/**
* @see javax.mail.Part#getSize()
*/
public int getSize() throws MessagingException {
- return wrapped.getSize();
+ return getWrappedMessage().getSize();
}
/**
* @see javax.mail.Part#getLineCount()
*/
public int getLineCount() throws MessagingException {
- return wrapped.getLineCount();
+ return getWrappedMessage().getLineCount();
}
/**
* @see javax.mail.Part#getContentType()
*/
public String getContentType() throws MessagingException {
- return wrapped.getContentType();
+ return getWrappedMessage().getContentType();
}
/**
* @see javax.mail.Part#isMimeType(java.lang.String)
*/
public boolean isMimeType(String mimeType) throws MessagingException {
- return wrapped.isMimeType(mimeType);
+ return getWrappedMessage().isMimeType(mimeType);
}
/**
* @see javax.mail.Part#getDisposition()
*/
public String getDisposition() throws MessagingException {
- return wrapped.getDisposition();
+ return getWrappedMessage().getDisposition();
}
/**
* @see javax.mail.internet.MimePart#getEncoding()
*/
public String getEncoding() throws MessagingException {
- return wrapped.getEncoding();
+ return getWrappedMessage().getEncoding();
}
/**
* @see javax.mail.internet.MimePart#getContentID()
*/
public String getContentID() throws MessagingException {
- return wrapped.getContentID();
+ return getWrappedMessage().getContentID();
}
/**
* @see javax.mail.internet.MimePart#getContentMD5()
*/
public String getContentMD5() throws MessagingException {
- return wrapped.getContentMD5();
+ return getWrappedMessage().getContentMD5();
}
/**
* @see javax.mail.Part#getDescription()
*/
public String getDescription() throws MessagingException {
- return wrapped.getDescription();
+ return getWrappedMessage().getDescription();
}
/**
* @see javax.mail.internet.MimePart#getContentLanguage()
*/
public String[] getContentLanguage() throws MessagingException {
- return wrapped.getContentLanguage();
+ return getWrappedMessage().getContentLanguage();
}
/**
* @see javax.mail.internet.MimeMessage#getMessageID()
*/
public String getMessageID() throws MessagingException {
- return wrapped.getMessageID();
+ return getWrappedMessage().getMessageID();
}
/**
* @see javax.mail.Part#getFileName()
*/
public String getFileName() throws MessagingException {
- return wrapped.getFileName();
+ return getWrappedMessage().getFileName();
}
/**
* @see javax.mail.Part#getInputStream()
*/
public InputStream getInputStream() throws IOException, MessagingException
{
- return wrapped.getInputStream();
+ return getWrappedMessage().getInputStream();
}
/**
* @see javax.mail.Part#getDataHandler()
*/
public DataHandler getDataHandler() throws MessagingException {
- return wrapped.getDataHandler();
+ return getWrappedMessage().getDataHandler();
}
/**
* @see javax.mail.Part#getContent()
*/
public Object getContent() throws IOException, MessagingException {
- return wrapped.getContent();
+ return getWrappedMessage().getContent();
}
/**
* @see javax.mail.Part#getHeader(java.lang.String)
*/
public String[] getHeader(String name) throws MessagingException {
- return wrapped.getHeader(name);
+ return getWrappedMessage().getHeader(name);
}
/**
@@ -344,14 +353,14 @@
*/
public String getHeader(String name, String delimiter)
throws MessagingException {
- return wrapped.getHeader(name, delimiter);
+ return getWrappedMessage().getHeader(name, delimiter);
}
/**
* @see javax.mail.Part#getAllHeaders()
*/
public Enumeration getAllHeaders() throws MessagingException {
- return wrapped.getAllHeaders();
+ return getWrappedMessage().getAllHeaders();
}
/**
@@ -359,7 +368,7 @@
*/
public Enumeration getMatchingHeaders(String[] names)
throws MessagingException {
- return wrapped.getMatchingHeaders(names);
+ return getWrappedMessage().getMatchingHeaders(names);
}
/**
@@ -367,14 +376,14 @@
*/
public Enumeration getNonMatchingHeaders(String[] names)
throws MessagingException {
- return wrapped.getNonMatchingHeaders(names);
+ return getWrappedMessage().getNonMatchingHeaders(names);
}
/**
* @see javax.mail.internet.MimePart#getAllHeaderLines()
*/
public Enumeration getAllHeaderLines() throws MessagingException {
- return wrapped.getAllHeaderLines();
+ return getWrappedMessage().getAllHeaderLines();
}
/**
@@ -382,7 +391,7 @@
*/
public Enumeration getMatchingHeaderLines(String[] names)
throws MessagingException {
- return wrapped.getMatchingHeaderLines(names);
+ return getWrappedMessage().getMatchingHeaderLines(names);
}
/**
@@ -390,84 +399,84 @@
*/
public Enumeration getNonMatchingHeaderLines(String[] names)
throws MessagingException {
- return wrapped.getNonMatchingHeaderLines(names);
+ return getWrappedMessage().getNonMatchingHeaderLines(names);
}
/**
* @see javax.mail.Message#getFlags()
*/
public Flags getFlags() throws MessagingException {
- return wrapped.getFlags();
+ return getWrappedMessage().getFlags();
}
/**
* @see javax.mail.Message#isSet(javax.mail.Flags.Flag)
*/
public boolean isSet(Flags.Flag flag) throws MessagingException {
- return wrapped.isSet(flag);
+ return getWrappedMessage().isSet(flag);
}
/**
* @see javax.mail.internet.MimeMessage#getSender()
*/
public Address getSender() throws MessagingException {
- return wrapped.getSender();
+ return getWrappedMessage().getSender();
}
/**
* @see javax.mail.Message#match(javax.mail.search.SearchTerm)
*/
public boolean match(SearchTerm arg0) throws MessagingException {
- return wrapped.match(arg0);
+ return getWrappedMessage().match(arg0);
}
/**
* @see javax.mail.internet.MimeMessage#getRawInputStream()
*/
public InputStream getRawInputStream() throws MessagingException {
- return wrapped.getRawInputStream();
+ return getWrappedMessage().getRawInputStream();
}
/**
* @see javax.mail.Message#getFolder()
*/
public Folder getFolder() {
- return wrapped.getFolder();
+ return getWrappedMessage().getFolder();
}
/**
* @see javax.mail.Message#getMessageNumber()
*/
public int getMessageNumber() {
- return wrapped.getMessageNumber();
+ return getWrappedMessage().getMessageNumber();
}
/**
* @see javax.mail.Message#isExpunged()
*/
public boolean isExpunged() {
- return wrapped.isExpunged();
+ return getWrappedMessage().isExpunged();
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object arg0) {
- return wrapped.equals(arg0);
+ return getWrappedMessage().equals(arg0);
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
- return wrapped.hashCode();
+ return getWrappedMessage().hashCode();
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
- return wrapped.toString();
+ return getWrappedMessage().toString();
}
/*
@@ -478,24 +487,21 @@
* @see javax.mail.Message#setFrom(javax.mail.Address)
*/
public void setFrom(Address address) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setFrom(address);
+ getWrappedMessageForWriting().setFrom(address);
}
/**
* @see javax.mail.Message#setFrom()
*/
public void setFrom() throws MessagingException {
- checkCopyOnWrite();
- wrapped.setFrom();
+ getWrappedMessageForWriting().setFrom();
}
/**
* @see javax.mail.Message#addFrom(javax.mail.Address[])
*/
public void addFrom(Address[] addresses) throws MessagingException {
- checkCopyOnWrite();
- wrapped.addFrom(addresses);
+ getWrappedMessageForWriting().addFrom(addresses);
}
/**
@@ -503,8 +509,7 @@
*/
public void setRecipients(Message.RecipientType type, Address[] addresses)
throws MessagingException {
- checkCopyOnWrite();
- wrapped.setRecipients(type, addresses);
+ getWrappedMessageForWriting().setRecipients(type, addresses);
}
/**
@@ -512,24 +517,21 @@
*/
public void addRecipients(Message.RecipientType type, Address[] addresses)
throws MessagingException {
- checkCopyOnWrite();
- wrapped.addRecipients(type, addresses);
+ getWrappedMessageForWriting().addRecipients(type, addresses);
}
/**
* @see javax.mail.Message#setReplyTo(javax.mail.Address[])
*/
public void setReplyTo(Address[] addresses) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setReplyTo(addresses);
+ getWrappedMessageForWriting().setReplyTo(addresses);
}
/**
* @see javax.mail.Message#setSubject(java.lang.String)
*/
public void setSubject(String subject) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setSubject(subject);
+ getWrappedMessageForWriting().setSubject(subject);
}
/**
@@ -537,48 +539,42 @@
*/
public void setSubject(String subject, String charset)
throws MessagingException {
- checkCopyOnWrite();
- wrapped.setSubject(subject, charset);
+ getWrappedMessageForWriting().setSubject(subject, charset);
}
/**
* @see javax.mail.Message#setSentDate(java.util.Date)
*/
public void setSentDate(Date d) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setSentDate(d);
+ getWrappedMessageForWriting().setSentDate(d);
}
/**
* @see javax.mail.Part#setDisposition(java.lang.String)
*/
public void setDisposition(String disposition) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setDisposition(disposition);
+ getWrappedMessageForWriting().setDisposition(disposition);
}
/**
* @see javax.mail.internet.MimeMessage#setContentID(java.lang.String)
*/
public void setContentID(String cid) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setContentID(cid);
+ getWrappedMessageForWriting().setContentID(cid);
}
/**
* @see javax.mail.internet.MimePart#setContentMD5(java.lang.String)
*/
public void setContentMD5(String md5) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setContentMD5(md5);
+ getWrappedMessageForWriting().setContentMD5(md5);
}
/**
* @see javax.mail.Part#setDescription(java.lang.String)
*/
public void setDescription(String description) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setDescription(description);
+ getWrappedMessageForWriting().setDescription(description);
}
/**
@@ -586,8 +582,7 @@
*/
public void setDescription(String description, String charset)
throws MessagingException {
- checkCopyOnWrite();
- wrapped.setDescription(description, charset);
+ getWrappedMessageForWriting().setDescription(description, charset);
}
/**
@@ -595,109 +590,99 @@
*/
public void setContentLanguage(String[] languages)
throws MessagingException {
- checkCopyOnWrite();
- wrapped.setContentLanguage(languages);
+ getWrappedMessageForWriting().setContentLanguage(languages);
}
/**
* @see javax.mail.Part#setFileName(java.lang.String)
*/
public void setFileName(String filename) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setFileName(filename);
+ getWrappedMessageForWriting().setFileName(filename);
}
/**
* @see javax.mail.Part#setDataHandler(javax.activation.DataHandler)
*/
public void setDataHandler(DataHandler dh) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setDataHandler(dh);
+ getWrappedMessageForWriting().setDataHandler(dh);
}
/**
* @see javax.mail.Part#setContent(java.lang.Object, java.lang.String)
*/
public void setContent(Object o, String type) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setContent(o, type);
+ getWrappedMessageForWriting().setContent(o, type);
}
/**
* @see javax.mail.Part#setText(java.lang.String)
*/
public void setText(String text) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setText(text);
+ getWrappedMessageForWriting().setText(text);
}
/**
* @see javax.mail.internet.MimePart#setText(java.lang.String,
java.lang.String)
*/
public void setText(String text, String charset) throws MessagingException
{
- checkCopyOnWrite();
- wrapped.setText(text, charset);
+ getWrappedMessageForWriting().setText(text, charset);
}
/**
* @see javax.mail.Part#setContent(javax.mail.Multipart)
*/
public void setContent(Multipart mp) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setContent(mp);
+ getWrappedMessageForWriting().setContent(mp);
}
+ /**
+ * This does not need a writable message
+ * @see javax.mail.Message#reply(boolean)
+ */
public Message reply(boolean replyToAll) throws MessagingException {
- checkCopyOnWrite();
- return wrapped.reply(replyToAll);
+ return getWrappedMessage().reply(replyToAll);
}
/**
* @see javax.mail.Part#setHeader(java.lang.String, java.lang.String)
*/
public void setHeader(String name, String value) throws MessagingException
{
- checkCopyOnWrite();
- wrapped.setHeader(name, value);
+ getWrappedMessageForWriting().setHeader(name, value);
}
/**
* @see javax.mail.Part#addHeader(java.lang.String, java.lang.String)
*/
public void addHeader(String name, String value) throws MessagingException
{
- checkCopyOnWrite();
- wrapped.addHeader(name, value);
+ getWrappedMessageForWriting().addHeader(name, value);
}
/**
* @see javax.mail.Part#removeHeader(java.lang.String)
*/
public void removeHeader(String name) throws MessagingException {
- checkCopyOnWrite();
- wrapped.removeHeader(name);
+ getWrappedMessageForWriting().removeHeader(name);
}
/**
* @see javax.mail.internet.MimePart#addHeaderLine(java.lang.String)
*/
public void addHeaderLine(String line) throws MessagingException {
- checkCopyOnWrite();
- wrapped.addHeaderLine(line);
+ getWrappedMessageForWriting().addHeaderLine(line);
}
/**
* @see javax.mail.Message#setFlags(javax.mail.Flags, boolean)
*/
public void setFlags(Flags flag, boolean set) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setFlags(flag, set);
+ getWrappedMessageForWriting().setFlags(flag, set);
}
/**
* @see javax.mail.Message#saveChanges()
*/
public void saveChanges() throws MessagingException {
- checkCopyOnWrite();
- wrapped.saveChanges();
+ getWrappedMessageForWriting().saveChanges();
}
/*
@@ -709,8 +694,7 @@
*/
public void addRecipients(Message.RecipientType type, String addresses)
throws MessagingException {
- checkCopyOnWrite();
- wrapped.addRecipients(type, addresses);
+ getWrappedMessageForWriting().addRecipients(type, addresses);
}
/**
@@ -718,16 +702,14 @@
*/
public void setRecipients(Message.RecipientType type, String addresses)
throws MessagingException {
- checkCopyOnWrite();
- wrapped.setRecipients(type, addresses);
+ getWrappedMessageForWriting().setRecipients(type, addresses);
}
/**
* @see javax.mail.internet.MimeMessage#setSender(javax.mail.Address)
*/
public void setSender(Address arg0) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setSender(arg0);
+ getWrappedMessageForWriting().setSender(arg0);
}
/**
@@ -735,31 +717,14 @@
*/
public void addRecipient(RecipientType arg0, Address arg1)
throws MessagingException {
- checkCopyOnWrite();
- wrapped.addRecipient(arg0, arg1);
+ getWrappedMessageForWriting().addRecipient(arg0, arg1);
}
/**
* @see javax.mail.Message#setFlag(javax.mail.Flags.Flag, boolean)
*/
public void setFlag(Flag arg0, boolean arg1) throws MessagingException {
- checkCopyOnWrite();
- wrapped.setFlag(arg0, arg1);
- }
-
- /**
- * @see org.apache.avalon.framework.activity.Disposable#dispose()
- */
- public synchronized void dispose() {
- if (wrapped != null) {
- refCount.decrementReferenceCount();
- if (refCount.getReferenceCount()<=0) {
- if (wrapped instanceof Disposable) {
- ((Disposable) wrapped).dispose();
- }
- }
- wrapped = null;
- }
+ getWrappedMessageForWriting().setFlag(arg0, arg1);
}
/**
@@ -775,14 +740,8 @@
* @throws MessagingException
*/
public long getMessageSize() throws MessagingException {
- return MimeMessageUtil.getMessageSize(wrapped);
- }
-
- /**
- * @return
- */
- public MimeMessage getWrappedMessage() {
- return wrapped;
+ return MimeMessageUtil.getMessageSize(getWrappedMessage());
}
}
+
Modified:
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageUtil.java
URL:
http://svn.apache.org/viewcvs/james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageUtil.java?rev=406350&r1=406349&r2=406350&view=diff
==============================================================================
---
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageUtil.java
(original)
+++
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageUtil.java
Sun May 14 08:10:45 2006
@@ -65,6 +65,19 @@
return;
}
}
+ writeToInternal(message, headerOs, bodyOs, ignoreList);
+ }
+
+ /**
+ * @param message
+ * @param headerOs
+ * @param bodyOs
+ * @param ignoreList
+ * @throws MessagingException
+ * @throws IOException
+ * @throws UnsupportedDataTypeException
+ */
+ public static void writeToInternal(MimeMessage message, OutputStream
headerOs, OutputStream bodyOs, String[] ignoreList) throws MessagingException,
IOException, UnsupportedDataTypeException {
if(message.getMessageID() == null) {
message.saveChanges();
}
@@ -167,6 +180,18 @@
private static void writeHeadersTo(MimeMessage message, OutputStream
headerOs, String[] ignoreList) throws MessagingException {
//Write the headers (minus ignored ones)
Enumeration headers = message.getNonMatchingHeaderLines(ignoreList);
+ writeHeadersTo(headers, headerOs);
+ }
+
+ /**
+ * Write the message headers to the given outputstream
+ *
+ * @param message
+ * @param headerOs
+ * @param ignoreList
+ * @throws MessagingException
+ */
+ public static void writeHeadersTo(Enumeration headers, OutputStream
headerOs) throws MessagingException {
PrintWriter hos = new InternetPrintWriter(new BufferedWriter(new
OutputStreamWriter(headerOs), 512), true);
while (headers.hasMoreElements()) {
hos.println((String)headers.nextElement());
Modified:
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageWrapper.java
URL:
http://svn.apache.org/viewcvs/james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageWrapper.java?rev=406350&r1=406349&r2=406350&view=diff
==============================================================================
---
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageWrapper.java
(original)
+++
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageWrapper.java
Sun May 14 08:10:45 2006
@@ -36,6 +36,7 @@
import java.util.Enumeration;
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 org.apache.mailet.RFC2822Headers;
@@ -118,7 +119,8 @@
// this probably speed up things
if (((MimeMessageWrapper) original).headers != null) {
ByteArrayOutputStream temp = new ByteArrayOutputStream();
- ((MailHeaders) ((MimeMessageWrapper)
original).headers).writeTo(temp);
+ InternetHeaders ih = ((MimeMessageWrapper) original).headers;
+ MimeMessageUtil.writeHeadersTo(ih.getAllHeaderLines(),temp);
headers = createInternetHeaders(new
ByteArrayInputStream(temp.toByteArray()));
headersModified = ((MimeMessageWrapper)
original).headersModified;
}
@@ -193,19 +195,22 @@
if (messageParsed) {
//Another thread has already loaded this message
return;
- }
- sourceIn = null;
- try {
- sourceIn = source.getInputStream();
-
- parse(sourceIn);
- // TODO is it ok?
- saved = true;
-
- } catch (IOException ioe) {
- IOUtil.shutdownStream(sourceIn);
+ } else if (source != null) {
sourceIn = null;
- throw new MessagingException("Unable to parse stream: " +
ioe.getMessage(), ioe);
+ 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");
}
}
@@ -222,7 +227,7 @@
* Rewritten for optimization purposes
*/
public synchronized void writeTo(OutputStream os) throws IOException,
MessagingException {
- if (!isModified()) {
+ 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();
@@ -251,7 +256,7 @@
}
public synchronized void writeTo(OutputStream headerOs, OutputStream
bodyOs, String[] ignoreList) throws IOException, MessagingException {
- if (!isModified()) {
+ if (source != null && !isModified()) {
//We do not want to instantiate the message... just read from
source
// and write to this outputstream
@@ -271,7 +276,7 @@
IOUtil.shutdownStream(in);
}
} else {
- MimeMessageUtil.writeTo(this, headerOs, bodyOs, ignoreList);
+ MimeMessageUtil.writeToInternal(this, headerOs, bodyOs,
ignoreList);
}
}
@@ -328,7 +333,7 @@
* Returns size of message, ie headers and content
*/
public long getMessageSize() throws MessagingException {
- if (!isModified()) {
+ if (source != null && !isModified()) {
try {
return source.getMessageSize();
} catch (IOException ioe) {
@@ -449,8 +454,8 @@
if (sourceIn != null) {
IOUtil.shutdownStream(sourceIn);
}
- if (source instanceof Disposable) {
- ((Disposable)source).dispose();
+ if (source != null) {
+ ContainerUtil.dispose(source);
}
}
Modified:
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageCopyOnWriteProxyTest.java
URL:
http://svn.apache.org/viewcvs/james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageCopyOnWriteProxyTest.java?rev=406350&r1=406349&r2=406350&view=diff
==============================================================================
---
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageCopyOnWriteProxyTest.java
(original)
+++
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageCopyOnWriteProxyTest.java
Sun May 14 08:10:45 2006
@@ -20,21 +20,19 @@
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
-import javax.mail.util.SharedByteArrayInputStream;
-
import javax.mail.MessagingException;
+import javax.mail.Session;
import javax.mail.internet.MimeMessage;
+import javax.mail.util.SharedByteArrayInputStream;
-import java.io.IOException;
import java.util.ArrayList;
+import java.util.Properties;
public class MimeMessageCopyOnWriteProxyTest extends MimeMessageFromStreamTest
{
- MimeMessageCopyOnWriteProxy mw = null;
String content = "Subject: foo\r\nContent-Transfer-Encoding2: plain";
String sep = "\r\n\r\n";
String body = "bar\r\n.\r\n";
- MailImpl mail;
protected MimeMessage getMessageFromSources(String sources) throws
Exception {
MimeMessageInputStreamSource mmis = null;
@@ -46,20 +44,11 @@
// return new MimeMessage(Session.getDefaultInstance(new
Properties()),new ByteArrayInputStream(sources.getBytes()));
}
- protected void setUp() throws Exception {
- mw = (MimeMessageCopyOnWriteProxy)
getMessageFromSources(content+sep+body);
- }
-
-
- protected void tearDown() throws Exception {
- ContainerUtil.dispose(mw);
- }
-
-
- public void testMessageCloning1() throws MessagingException, IOException {
+ public void testMessageCloning1() throws Exception {
ArrayList r = new ArrayList();
r.add(new MailAddress("[EMAIL PROTECTED]"));
- mail = new MailImpl("test",new MailAddress("[email protected]"),r,mw);
+ MimeMessageCopyOnWriteProxy messageFromSources =
(MimeMessageCopyOnWriteProxy) getMessageFromSources(content+sep+body);
+ MailImpl mail = new MailImpl("test",new
MailAddress("[email protected]"),r,messageFromSources);
MailImpl m2 = (MailImpl) mail.duplicate();
System.out.println("mail: "+getReferences(mail.getMessage())+" m2:
"+getReferences(m2.getMessage()));
assertNotSame(m2,mail);
@@ -74,13 +63,17 @@
// test it is different after a write operation!
mail.getMessage().setSubject("new Subject");
assertTrue(!isSameMimeMessage(m2.getMessage(),mail.getMessage()));
+ ContainerUtil.dispose(mail);
+ ContainerUtil.dispose(m2);
+ ContainerUtil.dispose(messageFromSources);
}
- public void testMessageCloning2() throws MessagingException, IOException {
+ public void testMessageCloning2() throws Exception {
ArrayList r = new ArrayList();
r.add(new MailAddress("[EMAIL PROTECTED]"));
- mail = new MailImpl("test",new MailAddress("[email protected]"),r,mw);
+ MimeMessageCopyOnWriteProxy messageFromSources =
(MimeMessageCopyOnWriteProxy) getMessageFromSources(content+sep+body);
+ MailImpl mail = new MailImpl("test",new
MailAddress("[email protected]"),r,messageFromSources);
MailImpl m2 = (MailImpl) mail.duplicate();
System.out.println("mail: "+getReferences(mail.getMessage())+" m2:
"+getReferences(m2.getMessage()));
assertNotSame(m2,mail);
@@ -114,12 +107,19 @@
m2clone.getMessage().setSubject("new Subject 2");
m2clone.getMessage().setText("new Body 3");
assertTrue(isSameMimeMessage(m2clone.getMessage(),mm));
+ ContainerUtil.dispose(mail);
+ ContainerUtil.dispose(messageFromSources);
}
- public void testMessageAvoidCloning() throws MessagingException,
IOException {
+ /**
+ * If I create a new MimeMessageCopyOnWriteProxy from another
MimeMessageCopyOnWriteProxy,
+ * I remove references to the first and I change the second, then it
should not clone
+ */
+ public void testMessageAvoidCloning() throws Exception {
ArrayList r = new ArrayList();
r.add(new MailAddress("[EMAIL PROTECTED]"));
- mail = new MailImpl("test",new MailAddress("[email protected]"),r,mw);
+ MimeMessageCopyOnWriteProxy messageFromSources =
(MimeMessageCopyOnWriteProxy) getMessageFromSources(content+sep+body);
+ MailImpl mail = new MailImpl("test",new
MailAddress("[email protected]"),r,messageFromSources);
// cloning the message
Mail mailClone = mail.duplicate();
assertTrue(isSameMimeMessage(mailClone.getMessage(),mail.getMessage()));
@@ -127,6 +127,10 @@
assertNotSame(mail.getMessage(),mailClone.getMessage());
// dispose mail and check that the clone has still a valid message and
it is the same!
((MailImpl) mail).dispose();
+ ContainerUtil.dispose(messageFromSources);
+ // need to add a gc and a wait, because the original mimemessage
should be finalized before the test.
+ System.gc();
+ Thread.sleep(1000);
// dumb test
assertTrue(isSameMimeMessage(mailClone.getMessage(),mailClone.getMessage()));
// change the message that should be not referenced by mail that has
@@ -134,13 +138,41 @@
mailClone.getMessage().setSubject("new Subject 2");
mailClone.getMessage().setText("new Body 3");
assertTrue(isSameMimeMessage(mailClone.getMessage(),mm));
+ ContainerUtil.dispose(mailClone);
+ ContainerUtil.dispose(mm);
+ }
+
+
+ /**
+ * If I create a new MimeMessageCopyOnWriteProxy from a MimeMessage and I
change the new
+ * message, the original should be unaltered and the proxy should clone
the message.
+ */
+ public void testMessageCloning3() throws Exception {
+ ArrayList r = new ArrayList();
+ r.add(new MailAddress("[EMAIL PROTECTED]"));
+ MimeMessage m = new MimeMessage(Session.getDefaultInstance(new
Properties(null)));
+ m.setText("CIPS");
+ MailImpl mail = new MailImpl("test",new
MailAddress("[email protected]"),r,m);
+ assertTrue(isSameMimeMessage(m,mail.getMessage()));
+ // change the message that should be not referenced by mail that has
+ // been disposed, so it should not clone it!
+ System.gc();
+ Thread.sleep(100);
+ mail.getMessage().setSubject("new Subject 2");
+ mail.getMessage().setText("new Body 3");
+ System.gc();
+ Thread.sleep(100);
+ assertFalse(isSameMimeMessage(m,mail.getMessage()));
+ ContainerUtil.dispose(mail);
+ ContainerUtil.dispose(m);
}
- public void testMessageDisposing() throws MessagingException, IOException {
+ public void testMessageDisposing() throws Exception {
ArrayList r = new ArrayList();
r.add(new MailAddress("[EMAIL PROTECTED]"));
- mail = new MailImpl("test",new MailAddress("[email protected]"),r,mw);
+ MimeMessageCopyOnWriteProxy messageFromSources =
(MimeMessageCopyOnWriteProxy) getMessageFromSources(content+sep+body);
+ MailImpl mail = new MailImpl("test",new
MailAddress("[email protected]"),r,messageFromSources);
// cloning the message
MailImpl mailClone = (MailImpl) mail.duplicate();
mail.dispose();
@@ -152,6 +184,55 @@
assertNull(mailClone.getMessage());
assertNull(mail.getMessage());
+ ContainerUtil.dispose(mail);
+ ContainerUtil.dispose(messageFromSources);
+ }
+
+ public void testNPE1() throws MessagingException, InterruptedException {
+ ArrayList recipients = new ArrayList();
+ recipients.add(new MailAddress("[EMAIL PROTECTED]"));
+ MimeMessageCopyOnWriteProxy mw = new MimeMessageCopyOnWriteProxy(
+ new MimeMessageInputStreamSource(
+ "test",
+ new SharedByteArrayInputStream(
+ ("Return-path: [EMAIL PROTECTED]"+
+ "Content-Transfer-Encoding: plain\r\n"+
+ "Subject: test\r\n\r\n"+
+ "Body Text\r\n").getBytes())));
+
+ MimeMessageCopyOnWriteProxy mw2 = new MimeMessageCopyOnWriteProxy(mw);
+ ContainerUtil.dispose(mw2);
+ mw2 = null;
+ System.gc();
+ Thread.sleep(1000);
+ // the NPE was inside this call
+ mw.getMessageSize();
+ ContainerUtil.dispose(mw);
+ }
+
+
+ /**
+ * This test throw a NullPointerException when the original message was
created by
+ * a MimeMessageInputStreamSource.
+ */
+ public void testMessageCloningViaCoW3() throws Exception {
+ MimeMessage mmorig = getSimpleMessage();
+
+ MimeMessage mm = new MimeMessageCopyOnWriteProxy(mmorig);
+
+ ContainerUtil.dispose(mmorig);
+ mmorig = null;
+ System.gc();
+ Thread.sleep(200);
+
+ try {
+ mm.writeTo(System.out);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Exception while writing the message to output");
+ }
+
+ ContainerUtil.dispose(mmorig);
}
private static String getReferences(MimeMessage m) {
Modified:
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageTest.java
URL:
http://svn.apache.org/viewcvs/james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageTest.java?rev=406350&r1=406349&r2=406350&view=diff
==============================================================================
---
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageTest.java
(original)
+++
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageTest.java
Sun May 14 08:10:45 2006
@@ -315,18 +315,46 @@
MimeMessage mmorig = getSimpleMessage();
MimeMessage mm = new MimeMessageCopyOnWriteProxy(mmorig);
-
+
MimeMessage mm2 = new MimeMessageCopyOnWriteProxy(mm);
mm2.setHeader("Subject", "Modified");
ContainerUtil.dispose(mm2);
+ System.gc();
+ Thread.sleep(200);
//((Disposable)mail_dup.getMessage()).dispose();
mm.setHeader("Subject", "Modified");
+ ContainerUtil.dispose(mm);
ContainerUtil.dispose(mmorig);
+ }
+
+ /**
+ * This test throw a NullPointerException when the original message was
created by
+ * a MimeMessageInputStreamSource.
+ */
+ public void testMessageCloningViaCoW2() throws Exception {
+ MimeMessage mmorig = getSimpleMessage();
+
+ MimeMessage mm = new MimeMessageCopyOnWriteProxy(mmorig);
+
+ MimeMessage mm2 = new MimeMessageCopyOnWriteProxy(mm);
+
ContainerUtil.dispose(mm);
+ mm = null;
+ System.gc();
+ Thread.sleep(200);
+
+ try {
+ mm2.writeTo(System.out);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Exception while writing the message to output");
+ }
+ ContainerUtil.dispose(mm2);
+ ContainerUtil.dispose(mmorig);
}
}
Modified:
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageWrapperTest.java
URL:
http://svn.apache.org/viewcvs/james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageWrapperTest.java?rev=406350&r1=406349&r2=406350&view=diff
==============================================================================
---
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageWrapperTest.java
(original)
+++
james/server/branches/v2.3/src/test/org/apache/james/core/MimeMessageWrapperTest.java
Sun May 14 08:10:45 2006
@@ -147,6 +147,19 @@
}
}
+ /**
+ * See JAMES-474
+ * MimeMessageWrapper(MimeMessage) should clone the original message.
+ */
+ public void testMessageCloned() throws MessagingException, IOException,
InterruptedException {
+ MimeMessageWrapper mmw = new MimeMessageWrapper(mw);
+ ContainerUtil.dispose(mw);
+ mw = null;
+ System.gc();
+ Thread.sleep(200);
+ mmw.writeTo(System.out);
+ }
+
/*
* Class under test for String getSubject()
*/
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]