FileDocCategorySizeDatePackage
MailImpl.javaAPI DocApache James 2.3.121915Fri Jan 12 12:56:22 GMT 2007org.apache.james.core

MailImpl

public class MailImpl extends Object implements org.apache.avalon.framework.activity.Disposable, org.apache.mailet.Mail

Wraps a MimeMessage adding routing information (from SMTP) and some simple API enhancements.

From James version > 2.2.0a8 "mail attributes" have been added. Backward and forward compatibility is supported: messages stored in file repositories without attributes by James version <= 2.2.0a8 will be processed by later versions as having an empty attributes hashmap; messages stored in file repositories with attributes by James version > 2.2.0a8 will be processed by previous versions, ignoring the attributes.

version
CVS $Revision: 494012 $ $Date: 2007-01-08 11:23:58 +0100 (Mo, 08 Jan 2007) $

Fields Summary
public static final long
serialVersionUID
We hardcode the serialVersionUID so that from James 1.2 on, MailImpl will be deserializable (so your mail doesn't get lost)
private String
errorMessage
The error message, if any, associated with this mail.
private String
state
The state of this mail, which determines how it is processed.
private MimeMessage
message
The MimeMessage that holds the mail data.
private org.apache.mailet.MailAddress
sender
The sender of this mail.
private Collection
recipients
The collection of recipients to whom this mail was sent.
private String
name
The identifier for this mail message
private String
remoteHost
The remote host from which this mail was sent.
private String
remoteAddr
The remote address from which this mail was sent.
private Date
lastUpdated
The last time this message was updated.
private HashMap
attributes
Attributes added to this MailImpl instance
Constructors Summary
public MailImpl()
A constructor that creates a new, uninitialized MailImpl

                 
      
        setState(Mail.DEFAULT);
        attributes = new HashMap();
    
public MailImpl(String name, org.apache.mailet.MailAddress sender, Collection recipients)
A constructor that creates a MailImpl with the specified name, sender, and recipients.

param
name the name of the MailImpl
param
sender the sender for this MailImpl
param
recipients the collection of recipients of this MailImpl

        this();
        this.name = name;
        this.sender = sender;
        this.recipients = null;

        // Copy the recipient list
        if (recipients != null) {
            Iterator theIterator = recipients.iterator();
            this.recipients = new ArrayList();
            while (theIterator.hasNext()) {
                this.recipients.add(theIterator.next());
            }
        }
    
public MailImpl(org.apache.mailet.Mail mail, String newName)

param
mail
param
newName
throws
MessagingException

        this(newName, mail.getSender(), mail.getRecipients(), mail.getMessage());
        setRemoteHost(mail.getRemoteHost());
        setRemoteAddr(mail.getRemoteAddr());
        setLastUpdated(mail.getLastUpdated());
        try {
            if (mail instanceof MailImpl) {
                setAttributesRaw((HashMap) cloneSerializableObject(((MailImpl) mail).getAttributesRaw()));
            } else {
                HashMap attribs = new HashMap();
                for (Iterator i = mail.getAttributeNames(); i.hasNext(); ) {
                    String hashKey = (String) i.next();
                    attribs.put(hashKey,cloneSerializableObject(mail.getAttribute(hashKey)));
                }
                setAttributesRaw(attribs);
            }
        } catch (IOException e) {
            // should never happen for in memory streams
            setAttributesRaw(new HashMap());
        } catch (ClassNotFoundException e) {
            // should never happen as we just serialized it
            setAttributesRaw(new HashMap());
        }
    
public MailImpl(String name, org.apache.mailet.MailAddress sender, Collection recipients, InputStream messageIn)
A constructor that creates a MailImpl with the specified name, sender, recipients, and message data.

param
name the name of the MailImpl
param
sender the sender for this MailImpl
param
recipients the collection of recipients of this MailImpl
param
messageIn a stream containing the message source

        this(name, sender, recipients);
        MimeMessageSource source = new MimeMessageInputStreamSource(name, messageIn);
        this.setMessage(new MimeMessageCopyOnWriteProxy(source));
    
public MailImpl(String name, org.apache.mailet.MailAddress sender, Collection recipients, MimeMessage message)
A constructor that creates a MailImpl with the specified name, sender, recipients, and MimeMessage.

param
name the name of the MailImpl
param
sender the sender for this MailImpl
param
recipients the collection of recipients of this MailImpl
param
message the MimeMessage associated with this MailImpl

        this(name, sender, recipients);
        this.setMessage(new MimeMessageCopyOnWriteProxy(message));
    
public MailImpl(MimeMessage message)
A constructor which will attempt to obtain sender and recipients from the headers of the MimeMessage supplied.

param
message - a MimeMessage from which to construct a Mail

        this();
        MailAddress sender = getReturnPath(message);
        Collection recipients = null;
        Address[] addresses = message.getRecipients(MimeMessage.RecipientType.TO);
        if (addresses != null) {
            recipients = new ArrayList();
            for (int i = 0; i < addresses.length; i++) {
                try {
                    recipients.add(new MailAddress(new InternetAddress(addresses[i].toString(), false)));
                } catch (ParseException pe) {
                    // RFC 2822 section 3.4 allows To: fields without <>
                    // Let's give this one more try with <>.
                    try {
                        recipients.add(new MailAddress("<" + new InternetAddress(addresses[i].toString()).toString() + ">"));
                    } catch (ParseException _) {
                        throw new MessagingException("Could not parse address: " + addresses[i].toString() + " from " + message.getHeader(RFC2822Headers.TO, ", "), pe);
                    }
                }
            }
        }
        this.name = message.toString();
        this.sender = sender;
        this.recipients = recipients;
        this.setMessage(message);
    
Methods Summary
private static java.lang.ObjectcloneSerializableObject(java.lang.Object o)
This methods provide cloning for serializable objects. Mail Attributes are Serializable but not Clonable so we need a deep copy

param
input Object to be cloned
return
the cloned Object
throws
IOException
throws
ClassNotFoundException

        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(b);
        out.writeObject(o);
        out.flush();
        out.close();
        ByteArrayInputStream bi=new ByteArrayInputStream(b.toByteArray());
        ObjectInputStream in = new ObjectInputStream(bi);
        Object no = in.readObject();
        return no;
    
public voiddispose()

see
org.apache.avalon.framework.activity.Disposable#dispose()

        ContainerUtil.dispose(message);
        message = null;
    
public org.apache.mailet.Mailduplicate()
Duplicate the MailImpl.

return
a MailImpl that is a duplicate of this one

        return duplicate(name);
    
public org.apache.mailet.Mailduplicate(java.lang.String newName)
Duplicate the MailImpl, replacing the mail name with the one passed in as an argument.

param
newName the name for the duplicated mail
return
a MailImpl that is a duplicate of this one with a different name

        try {
            return new MailImpl(this, newName);
        } catch (MessagingException me) {
            // Ignored.  Return null in the case of an error.
        }
        return null;
    
public java.io.SerializablegetAttribute(java.lang.String key)

see
org.apache.mailet.Mail#getAttribute(String)
since
2.2.0

        return (Serializable)attributes.get(key);
    
public java.util.IteratorgetAttributeNames()

see
org.apache.mailet.Mail#getAttributeNames()
since
2.2.0

        return attributes.keySet().iterator();
    
public java.util.HashMapgetAttributesRaw()
This method is necessary, when Mail repositories needs to deal explicitly with storing Mail attributes as a Serializable Note: This method is not exposed in the Mail interface, it is for internal use by James only.

return
Serializable of the entire attributes collection
since
2.2.0

        return attributes;
    
public java.lang.StringgetErrorMessage()
Get the error message associated with this MailImpl.

return
the error message associated with this MailImpl

        return errorMessage;
    
public java.util.DategetLastUpdated()
Get the last updated time for this MailImpl.

return
the last updated time for this MailImpl

        return lastUpdated;
    
public javax.mail.internet.MimeMessagegetMessage()
Get the MimeMessage associated with this MailImpl.

return
the MimeMessage associated with this MailImpl

        return message;
    
public longgetMessageSize()

Return the size of the message including its headers. MimeMessage.getSize() method only returns the size of the message body.

Note: this size is not guaranteed to be accurate - see Sun's documentation of MimeMessage.getSize().

return
approximate size of full message including headers.
throws
MessagingException if a problem occurs while computing the message size

        return MimeMessageUtil.getMessageSize(message);
    
public java.lang.StringgetName()
Get the name of this MailImpl.

return
the name of this MailImpl

        return name;
    
public java.util.CollectiongetRecipients()
Get the recipients of this MailImpl.

return
the recipients of this MailImpl

        return recipients;
    
public java.lang.StringgetRemoteAddr()
Get the remote address associated with this MailImpl.

return
the remote address associated with this MailImpl

        return remoteAddr;
    
public java.lang.StringgetRemoteHost()
Get the remote host associated with this MailImpl.

return
the remote host associated with this MailImpl

        return remoteHost;
    
private org.apache.mailet.MailAddressgetReturnPath(javax.mail.internet.MimeMessage message)
Gets the MailAddress corresponding to the existing "Return-Path" of message. If missing or empty returns null,

        MailAddress mailAddress = null;
        String[] returnPathHeaders = message.getHeader(RFC2822Headers.RETURN_PATH);
        String returnPathHeader = null;
        if (returnPathHeaders != null) {
            returnPathHeader = returnPathHeaders[0];
            if (returnPathHeader != null) {
                returnPathHeader = returnPathHeader.trim();
                if (!returnPathHeader.equals("<>")) {
                    try {
                        mailAddress = new MailAddress(new InternetAddress(returnPathHeader, false));
                    } catch (ParseException pe) {
                        throw new MessagingException("Could not parse address: " + returnPathHeader + " from " + message.getHeader(RFC2822Headers.RETURN_PATH, ", "), pe);
                    }
                }
            }
        }
        return mailAddress;
    
public org.apache.mailet.MailAddressgetSender()
Get the sender of this MailImpl.

return
the sender of this MailImpl

        return sender;
    
public java.lang.StringgetState()
Get the state of this MailImpl.

return
the state of this MailImpl

        return state;
    
public booleanhasAttributes()

see
org.apache.mailet.Mail#hasAttributes()
since
2.2.0

        return !attributes.isEmpty();
    
private voidreadObject(java.io.ObjectInputStream in)
Read the MailImpl from an ObjectInputStream.

param
in the ObjectInputStream from which the object is read
throws
IOException if an error occurs while reading from the stream
throws
ClassNotFoundException ?
throws
ClassCastException if the serialized objects are not of the appropriate type

        try {
            Object obj = in.readObject();
            if (obj == null) {
                sender = null;
            } else if (obj instanceof String) {
                sender = new MailAddress((String) obj);
            } else if (obj instanceof MailAddress) {
                sender = (MailAddress) obj;
            }
        } catch (ParseException pe) {
            throw new IOException("Error parsing sender address: " + pe.getMessage());
        }
        recipients = (Collection) in.readObject();
        state = (String) in.readObject();
        errorMessage = (String) in.readObject();
        name = (String) in.readObject();
        remoteHost = (String) in.readObject();
        remoteAddr = (String) in.readObject();
        setLastUpdated((Date) in.readObject());
        // the following is under try/catch to be backwards compatible
        // with messages created with James version <= 2.2.0a8
        try {
            attributes = (HashMap) in.readObject();
        } catch (OptionalDataException ode) {
            if (ode.eof) {
                attributes = new HashMap();
            } else {
                throw ode;
            }
        }
    
public voidremoveAllAttributes()

see
org.apache.mailet.Mail#removeAllAttributes()
since
2.2.0

        attributes.clear();
    
public java.io.SerializableremoveAttribute(java.lang.String key)

see
org.apache.mailet.Mail#removeAttribute(String)
since
2.2.0

        return (Serializable)attributes.remove(key);
    
public java.io.SerializablesetAttribute(java.lang.String key, java.io.Serializable object)

see
org.apache.mailet.Mail#setAttribute(String,Serializable)
since
2.2.0

        return (Serializable)attributes.put(key, object);
    
public voidsetAttributesRaw(java.util.HashMap attr)
This method is necessary, when Mail repositories needs to deal explicitly with retriving Mail attributes as a Serializable Note: This method is not exposed in the Mail interface, it is for internal use by James only.

return
Serializable of the entire attributes collection
since
2.2.0

        this.attributes = (attr == null) ? new HashMap() : attr;
    
public voidsetErrorMessage(java.lang.String msg)
Set the error message associated with this MailImpl.

param
msg the new error message associated with this MailImpl

        this.errorMessage = msg;
    
public voidsetLastUpdated(java.util.Date lastUpdated)
Set the date this mail was last updated.

param
lastUpdated the date the mail was last updated

        // Make a defensive copy to ensure that the date
        // doesn't get changed external to the class
        if (lastUpdated != null) {
            lastUpdated = new Date(lastUpdated.getTime());
        }
        this.lastUpdated = lastUpdated;
    
public voidsetMessage(javax.mail.internet.MimeMessage message)
Set the MimeMessage associated with this MailImpl.

param
message the new MimeMessage associated with this MailImpl

        if (this.message != message) {
            // If a setMessage is called on a Mail that already have a message
            // (discouraged) we have to make sure that the message we remove is
            // correctly unreferenced and disposed, otherwise it will keep locks
            if (this.message != null) {
                ContainerUtil.dispose(this.message);
            }
            this.message = message;
        }
    
public voidsetName(java.lang.String name)
Set the name of this MailImpl.

param
name the name of this MailImpl

        this.name = name;
    
public voidsetRecipients(java.util.Collection recipients)
Set the recipients for this MailImpl.

param
recipients the recipients for this MailImpl

        this.recipients = recipients;
    
public voidsetRemoteAddr(java.lang.String remoteAddr)
Set the remote address associated with this MailImpl.

param
remoteAddr the new remote address associated with this MailImpl

        this.remoteAddr = remoteAddr;
    
public voidsetRemoteHost(java.lang.String remoteHost)
Set the remote address associated with this MailImpl.

param
remoteHost the new remote host associated with this MailImpl

        this.remoteHost = remoteHost;
    
public voidsetSender(org.apache.mailet.MailAddress sender)
Set the sender of this MailImpl.

param
sender the sender of this MailImpl

        this.sender = sender;
    
public voidsetState(java.lang.String state)
Set the state of this MailImpl.

param
state the state of this MailImpl

        this.state = state;
    
public voidwriteMessageTo(java.io.OutputStream out)
Writes the message out to an OutputStream.

param
out the OutputStream to which to write the content
throws
MessagingException if the MimeMessage is not set for this MailImpl
throws
IOException if an error occurs while reading or writing from the stream

        if (message != null) {
            message.writeTo(out);
        } else {
            throw new MessagingException("No message set for this MailImpl.");
        }
    
private voidwriteObject(java.io.ObjectOutputStream out)
Write the MailImpl to an ObjectOutputStream.

param
in the ObjectOutputStream to which the object is written
throws
IOException if an error occurs while writing to the stream

        out.writeObject(sender);
        out.writeObject(recipients);
        out.writeObject(state);
        out.writeObject(errorMessage);
        out.writeObject(name);
        out.writeObject(remoteHost);
        out.writeObject(remoteAddr);
        out.writeObject(lastUpdated);
        out.writeObject(attributes);