001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.mail;
018:
019: import java.io.PrintStream;
020: import java.io.PrintWriter;
021: import java.util.Collections;
022: import java.util.LinkedHashMap;
023: import java.util.Map;
024:
025: /**
026: * Exception thrown when a mail sending error is encountered.
027: * Can register failed messages with their exceptions.
028: *
029: * @author Dmitriy Kopylenko
030: * @author Juergen Hoeller
031: */
032: public class MailSendException extends MailException {
033:
034: private transient Map failedMessages;
035:
036: private Exception[] messageExceptions;
037:
038: /**
039: * Constructor for MailSendException.
040: * @param msg the detail message
041: */
042: public MailSendException(String msg) {
043: super (msg);
044: }
045:
046: /**
047: * Constructor for MailSendException.
048: * @param msg the detail message
049: * @param cause the root cause from the mail API in use
050: */
051: public MailSendException(String msg, Throwable cause) {
052: super (msg, cause);
053: }
054:
055: /**
056: * Constructor for registration of failed messages, with the
057: * messages that failed as keys, and the thrown exceptions as values.
058: * <p>The messages should be the same that were originally passed
059: * to the invoked send method.
060: * @param failedMessages Map of failed messages as keys and thrown
061: * exceptions as values
062: */
063: public MailSendException(Map failedMessages) {
064: super (null);
065: this .failedMessages = new LinkedHashMap(failedMessages);
066: this .messageExceptions = (Exception[]) failedMessages.values()
067: .toArray(new Exception[failedMessages.size()]);
068: }
069:
070: /**
071: * Return a Map with the failed messages as keys, and the thrown exceptions
072: * as values.
073: * <p>Note that a general mail server connection failure will not result
074: * in failed messages being returned here: A message will only be
075: * contained here if actually sending it was attempted but failed.
076: * <p>The messages will be the same that were originally passed to the
077: * invoked send method, that is, SimpleMailMessages in case of using
078: * the generic MailSender interface.
079: * <p>In case of sending MimeMessage instances via JavaMailSender,
080: * the messages will be of type MimeMessage.
081: * <p><b>NOTE:</b> This Map will not be available after serialization.
082: * Use {@link #getMessageExceptions()} in such a scenario, which will
083: * be available after serialization as well.
084: * @return the Map of failed messages as keys and thrown exceptions as
085: * values, or an empty Map if no failed messages
086: * @see SimpleMailMessage
087: * @see javax.mail.internet.MimeMessage
088: */
089: public final Map getFailedMessages() {
090: return (this .failedMessages != null ? this .failedMessages
091: : Collections.EMPTY_MAP);
092: }
093:
094: /**
095: * Return an array with thrown message exceptions.
096: * <p>Note that a general mail server connection failure will not result
097: * in failed messages being returned here: A message will only be
098: * contained here if actually sending it was attempted but failed.
099: * @return the array of thrown message exceptions,
100: * or an empty array if no failed messages
101: */
102: public final Exception[] getMessageExceptions() {
103: return (this .messageExceptions != null ? this .messageExceptions
104: : new Exception[0]);
105: }
106:
107: public String getMessage() {
108: StringBuffer sb = new StringBuffer();
109: String super Msg = super .getMessage();
110: sb.append(super Msg != null ? super Msg : "Failed messages: ");
111: for (int i = 0; i < this .messageExceptions.length; i++) {
112: Exception subEx = this .messageExceptions[i];
113: sb.append(subEx.toString());
114: if (i < this .messageExceptions.length - 1) {
115: sb.append("; ");
116: }
117: }
118: return sb.toString();
119: }
120:
121: public String toString() {
122: StringBuffer sb = new StringBuffer();
123: sb.append(getClass().getName()).append("; nested exceptions (");
124: sb.append(this .messageExceptions.length).append(") are:");
125: for (int i = 0; i < this .messageExceptions.length; i++) {
126: Exception subEx = this .messageExceptions[i];
127: sb.append('\n').append("Failed message ").append(i + 1)
128: .append(": ");
129: sb.append(subEx);
130: }
131: return sb.toString();
132: }
133:
134: public void printStackTrace(PrintStream ps) {
135: if (this .messageExceptions.length == 0) {
136: super .printStackTrace(ps);
137: } else {
138: ps.println(getClass().getName()
139: + "; nested exception details ("
140: + this .messageExceptions.length + ") are:");
141: for (int i = 0; i < this .messageExceptions.length; i++) {
142: Exception subEx = this .messageExceptions[i];
143: ps.println("Failed message " + (i + 1) + ":");
144: subEx.printStackTrace(ps);
145: }
146: }
147: }
148:
149: public void printStackTrace(PrintWriter pw) {
150: if (this .messageExceptions.length == 0) {
151: super .printStackTrace(pw);
152: } else {
153: pw.println(getClass().getName()
154: + "; nested exception details ("
155: + this .messageExceptions.length + ") are:");
156: for (int i = 0; i < this .messageExceptions.length; i++) {
157: Exception subEx = this .messageExceptions[i];
158: pw.println("Failed message " + (i + 1) + ":");
159: subEx.printStackTrace(pw);
160: }
161: }
162: }
163:
164: }
|