All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.mail.Transport Maven / Gradle / Ivy

/*
 * 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 javax.mail;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;

import javax.mail.event.TransportEvent;
import javax.mail.event.TransportListener;

/**
 * Abstract class modeling a message transport.
 *
 * @version $Rev$ $Date$
 */
public abstract class Transport extends Service {
    /**
     * Send a message to all recipient addresses the message contains (as returned by {@link Message#getAllRecipients()})
     * using message transports appropriate for each address. Message addresses are checked during submission,
     * but there is no guarantee that the ultimate address is valid or that the message will ever be delivered.
     * 

* {@link Message#saveChanges()} will be called before the message is actually sent. * * @param message the message to send * @throws MessagingException if there was a problem sending the message */ public static void send(final Message message) throws MessagingException { send(message, message.getAllRecipients()); } /** * Send a message to all addresses provided irrespective of any recipients contained in the message, * using message transports appropriate for each address. Message addresses are checked during submission, * but there is no guarantee that the ultimate address is valid or that the message will ever be delivered. *

* {@link Message#saveChanges()} will be called before the message is actually sent. * * @param message the message to send * @param addresses the addesses to send to * @throws MessagingException if there was a problem sending the message */ public static void send(final Message message, final Address[] addresses) throws MessagingException { sendInternal(message, addresses, null, null); } private static void sendInternal(final Message message, final Address[] addresses, final String user, final String password) throws MessagingException { if (addresses == null || addresses.length == 0) { throw new SendFailedException("No recipient addresses"); } final Session session = message.session; final Map> msgsByTransport = new HashMap>(); for (int i = 0; i < addresses.length; i++) { final Address address = addresses[i]; final Transport transport = session.getTransport(address); List

addrs = msgsByTransport.get(transport); if (addrs == null) { addrs = new ArrayList
(); msgsByTransport.put(transport, addrs); } addrs.add(address); } message.saveChanges(); // Since we might be sending to multiple protocols, we need to catch and process each exception // when we send and then throw a new SendFailedException when everything is done. Unfortunately, this // also means unwrapping the information in any SendFailedExceptions we receive and building // composite failed list. MessagingException chainedException = null; final List
sentAddresses = new ArrayList
(); final List
unsentAddresses = new ArrayList
(); final List
invalidAddresses = new ArrayList
(); for (final Iterator>> i = msgsByTransport.entrySet().iterator(); i.hasNext();) { final Entry> entry = i.next(); final Transport transport = entry.getKey(); final List
addrs = entry.getValue(); try { // we MUST connect to the transport before attempting to send. if(user != null) { transport.connect(user, password); } else { transport.connect(); } transport.sendMessage(message, addrs.toArray(new Address[addrs.size()])); // if we have to throw an exception because of another failure, these addresses need to // be in the valid list. Since we succeeded here, we can add these now. sentAddresses.addAll(addrs); } catch (final SendFailedException e) { // a true send failure. The exception contains a wealth of information about // the failures, including a potential chain of exceptions explaining what went wrong. We're // going to send a new one of these, so we need to merge the information. // add this to our exception chain if (chainedException == null) { chainedException = e; } else { chainedException.setNextException(e); } // now extract each of the address categories from Address[] exAddrs = e.getValidSentAddresses(); if (exAddrs != null) { for (int j = 0; j < exAddrs.length; j++) { sentAddresses.add(exAddrs[j]); } } exAddrs = e.getValidUnsentAddresses(); if (exAddrs != null) { for (int j = 0; j < exAddrs.length; j++) { unsentAddresses.add(exAddrs[j]); } } exAddrs = e.getInvalidAddresses(); if (exAddrs != null) { for (int j = 0; j < exAddrs.length; j++) { invalidAddresses.add(exAddrs[j]); } } } catch (final MessagingException e) { // add this to our exception chain if (chainedException == null) { chainedException = e; } else { chainedException.setNextException(e); } } finally { transport.close(); } } // if we have an exception chain then we need to throw a new exception giving the failure // information. if (chainedException != null) { // if we're only sending to a single transport (common), and we received a SendFailedException // as a result, then we have a fully formed exception already. Rather than wrap this in another // exception, we can just rethrow the one we have. if (msgsByTransport.size() == 1 && chainedException instanceof SendFailedException) { throw chainedException; } // create our lists for notification and exception reporting from this point on. final Address[] sent = sentAddresses.toArray(new Address[0]); final Address[] unsent = unsentAddresses.toArray(new Address[0]); final Address[] invalid = invalidAddresses.toArray(new Address[0]); throw new SendFailedException("Send failure", chainedException, sent, unsent, invalid); } } /** * Send a message. The message will be sent to all recipient * addresses specified in the message (as returned from the * Message method getAllRecipients). * The send method calls the saveChanges * method on the message before sending it. * * Use the specified user name and password to authenticate to * the mail server. * * @param msg the message to send * @param user the user name * @param password this user's password * @exception SendFailedException if the message could not * be sent to some or any of the recipients. * @exception MessagingException * @see Message#saveChanges * @see #send(Message) * @see javax.mail.SendFailedException * @since JavaMail 1.5 */ public static void send(final Message msg, final String user, final String password) throws MessagingException { send(msg, msg.getAllRecipients(), user, password); } /** * 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. * * Use the specified user name and password to authenticate to * the mail server. * * @param msg the message to send * @param addresses the addresses to which to send the message * @param user the user name * @param password this user's password * @exception SendFailedException if the message could not * be sent to some or any of the recipients. * @exception MessagingException * @see Message#saveChanges * @see #send(Message) * @see javax.mail.SendFailedException * @since JavaMail 1.5 */ public static void send(final Message msg, final Address[] addresses, final String user, final String password) throws MessagingException { sendInternal(msg, addresses, user, password); } /** * Constructor taking Session and URLName parameters required for {@link Service#Service(Session, URLName)}. * * @param session the Session this transport is for * @param name the location this transport is for */ public Transport(final Session session, final URLName name) { super(session, name); } /** * Send a message to the supplied addresses using this transport; if any of the addresses are * invalid then a {@link SendFailedException} is thrown. Whether the message is actually sent * to any of the addresses is undefined. *

* Unlike the static {@link #send(Message, Address[])} method, {@link Message#saveChanges()} is * not called. A {@link TransportEvent} will be sent to registered listeners once the delivery * attempt has been made. * * @param message the message to send * @param addresses list of addresses to send it to * @throws SendFailedException if the send failed * @throws MessagingException if there was a problem sending the message */ public abstract void sendMessage(Message message, Address[] addresses) throws MessagingException; private final Vector transportListeners = new Vector(); public void addTransportListener(final TransportListener listener) { transportListeners.add(listener); } public void removeTransportListener(final TransportListener listener) { transportListeners.remove(listener); } protected void notifyTransportListeners(final int type, final Address[] validSent, final Address[] validUnsent, final Address[] invalid, final Message message) { queueEvent(new TransportEvent(this, type, validSent, validUnsent, invalid, message), transportListeners); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy