Transportpublic abstract class Transport extends Service An abstract class that models a message transport.
Subclasses provide actual implementations.
Note that Transport extends the Service
class, which provides many common methods for naming transports,
connecting to transports, and listening to connection events. |
Fields Summary |
---|
private Vector | transportListeners |
Constructors Summary |
---|
public Transport(Session session, URLName urlname)Constructor.
super(session, urlname);
|
Methods Summary |
---|
public synchronized void | addTransportListener(javax.mail.event.TransportListener l)Add a listener for Transport events.
The default implementation provided here adds this listener
to an internal list of TransportListeners.
if (transportListeners == null)
transportListeners = new Vector();
transportListeners.addElement(l);
| protected void | notifyTransportListeners(int type, javax.mail.Address[] validSent, javax.mail.Address[] validUnsent, javax.mail.Address[] invalid, Message msg)Notify all TransportListeners. Transport implementations are
expected to use this method to broadcast TransportEvents.
The provided default implementation queues the event into
an internal event queue. An event dispatcher thread dequeues
events from the queue and dispatches them to the registered
TransportListeners. Note that the event dispatching occurs
in a separate thread, thus avoiding potential deadlock problems.
if (transportListeners == null)
return;
TransportEvent e = new TransportEvent(this, type, validSent,
validUnsent, invalid, msg);
queueEvent(e, transportListeners);
| public synchronized void | removeTransportListener(javax.mail.event.TransportListener l)Remove a listener for Transport events.
The default implementation provided here removes this listener
from the internal list of TransportListeners.
if (transportListeners != null)
transportListeners.removeElement(l);
| public static void | send(Message msg)Send a message. The message will be sent to all recipient
addresses specified in the message (as returned from the
Message method getAllRecipients ),
using message transports appropriate to each address. The
send method calls the saveChanges
method on the message before sending it.
If any of the recipient addresses is detected to be invalid by
the Transport during message submission, a SendFailedException
is thrown. Clients can get more detail about the failure by examining
the exception. Whether or not the message is still sent succesfully to
any valid addresses depends on the Transport implementation. See
SendFailedException for more details. Note also that success does
not imply that the message was delivered to the ultimate recipient,
as failures may occur in later stages of delivery. Once a Transport
accepts a message for delivery to a recipient, failures that occur later
should be reported to the user via another mechanism, such as
returning the undeliverable message.
Note that send is a static method that creates and
manages its own connection. Any connection associated with any
Transport instance used to invoke this method is ignored and not
used. This method should only be invoked using the form
Transport.send(msg); , and should never be invoked
using an instance variable.
msg.saveChanges(); // do this first
send0(msg, msg.getAllRecipients());
| public static void | send(Message msg, javax.mail.Address[] addresses)Send the message to the specified addresses, ignoring any
recipients specified in the message itself. The
send method calls the saveChanges
method on the message before sending it.
msg.saveChanges();
send0(msg, addresses);
| private static void | send0(Message msg, javax.mail.Address[] addresses)
if (addresses == null || addresses.length == 0)
throw new SendFailedException("No recipient addresses");
/*
* protocols is a hashtable containing the addresses
* indexed by address type
*/
Hashtable protocols = new Hashtable();
// Vectors of addresses
Vector invalid = new Vector();
Vector validSent = new Vector();
Vector validUnsent = new Vector();
for (int i = 0; i < addresses.length; i++) {
// is this address type already in the hashtable?
if (protocols.containsKey(addresses[i].getType())) {
Vector v = (Vector)protocols.get(addresses[i].getType());
v.addElement(addresses[i]);
} else {
// need to add a new protocol
Vector w = new Vector();
w.addElement(addresses[i]);
protocols.put(addresses[i].getType(), w);
}
}
int dsize = protocols.size();
if (dsize == 0)
throw new SendFailedException("No recipient addresses");
Session s = (msg.session != null) ? msg.session :
Session.getDefaultInstance(System.getProperties(), null);
Transport transport;
/*
* Optimize the case of a single protocol.
*/
if (dsize == 1) {
transport = s.getTransport(addresses[0]);
try {
transport.connect();
transport.sendMessage(msg, addresses);
} finally {
transport.close();
}
return;
}
/*
* More than one protocol. Have to do them one at a time
* and collect addresses and chain exceptions.
*/
MessagingException chainedEx = null;
boolean sendFailed = false;
Enumeration e = protocols.elements();
while (e.hasMoreElements()) {
Vector v = (Vector)e.nextElement();
Address[] protaddresses = new Address[v.size()];
v.copyInto(protaddresses);
// Get a Transport that can handle this address type.
if ((transport = s.getTransport(protaddresses[0])) == null) {
// Could not find an appropriate Transport ..
// Mark these addresses invalid.
for (int j = 0; j < protaddresses.length; j++)
invalid.addElement(protaddresses[j]);
continue;
}
try {
transport.connect();
transport.sendMessage(msg, protaddresses);
} catch (SendFailedException sex) {
sendFailed = true;
// chain the exception we're catching to any previous ones
if (chainedEx == null)
chainedEx = sex;
else
chainedEx.setNextException(sex);
// retrieve invalid addresses
Address[] a = sex.getInvalidAddresses();
if (a != null)
for (int j = 0; j < a.length; j++)
invalid.addElement(a[j]);
// retrieve validSent addresses
a = sex.getValidSentAddresses();
if (a != null)
for (int k = 0; k < a.length; k++)
validSent.addElement(a[k]);
// retrieve validUnsent addresses
Address[] c = sex.getValidUnsentAddresses();
if (c != null)
for (int l = 0; l < c.length; l++)
validUnsent.addElement(c[l]);
} catch (MessagingException mex) {
sendFailed = true;
// chain the exception we're catching to any previous ones
if (chainedEx == null)
chainedEx = mex;
else
chainedEx.setNextException(mex);
} finally {
transport.close();
}
}
// done with all protocols. throw exception if something failed
if (sendFailed || invalid.size() != 0 || validUnsent.size() != 0) {
Address[] a = null, b = null, c = null;
// copy address vectors into arrays
if (validSent.size() > 0) {
a = new Address[validSent.size()];
validSent.copyInto(a);
}
if (validUnsent.size() > 0) {
b = new Address[validUnsent.size()];
validUnsent.copyInto(b);
}
if (invalid.size() > 0) {
c = new Address[invalid.size()];
invalid.copyInto(c);
}
throw new SendFailedException("Sending failed", chainedEx,
a, b, c);
}
| public abstract void | sendMessage(Message msg, javax.mail.Address[] addresses)Send the Message to the specified list of addresses. An appropriate
TransportEvent indicating the delivery status is delivered to any
TransportListener registered on this Transport. Also, if any of
the addresses is invalid, a SendFailedException is thrown.
Whether or not the message is still sent succesfully to
any valid addresses depends on the Transport implementation.
Unlike the static send method, the sendMessage
method does not call the saveChanges method on
the message; the caller should do so.
|
|