001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.mail;
019
020 import java.io.PrintStream;
021 import java.io.PrintWriter;
022
023 /**
024 * Exception thrown when a checked error occurs in commons-email.
025 * <p>
026 * Supports nesting, emulating JDK 1.4 behavior if necessary.
027 * <p>
028 * Adapted from FunctorException in Commons Collections.
029 *
030 * @author jakarta-commons
031 * @since 1.0
032 * @version $Id: EmailException.java 510812 2007-02-23 04:32:22Z dion $
033 */
034 public class EmailException
035 extends Exception
036 {
037 /** Serializable version identifier */
038 static final long serialVersionUID = 5550674499282474616L;
039
040 /**
041 * Does JDK support nested exceptions?
042 */
043 private static final boolean JDK_SUPPORTS_NESTED;
044
045 static
046 {
047 boolean flag = false;
048
049 try
050 {
051 Throwable.class.getDeclaredMethod("getCause", new Class[0]);
052 flag = true;
053 }
054 catch (NoSuchMethodException ex)
055 {
056 flag = false;
057 }
058
059 JDK_SUPPORTS_NESTED = flag;
060 }
061
062 /**
063 * Root cause of the exception
064 */
065 private final Throwable rootCause;
066
067 /**
068 * Constructs a new <code>EmailException</code> with no
069 * detail message.
070 */
071 public EmailException()
072 {
073 super();
074 this.rootCause = null;
075 }
076
077 /**
078 * Constructs a new <code>EmailException</code> with specified
079 * detail message.
080 *
081 * @param msg the error message.
082 */
083 public EmailException(String msg)
084 {
085 super(msg);
086 this.rootCause = null;
087 }
088
089 /**
090 * Constructs a new <code>EmailException</code> with specified
091 * nested <code>Throwable</code> root cause.
092 *
093 * @param rootCause the exception or error that caused this exception
094 * to be thrown.
095 */
096 public EmailException(Throwable rootCause)
097 {
098 super((rootCause == null) ? null : rootCause.getMessage());
099 this.rootCause = rootCause;
100 }
101
102 /**
103 * Constructs a new <code>EmailException</code> with specified
104 * detail message and nested <code>Throwable</code> root cause.
105 *
106 * @param msg the error message.
107 * @param rootCause the exception or error that caused this exception
108 * to be thrown.
109 */
110 public EmailException(String msg, Throwable rootCause)
111 {
112 super(msg);
113 this.rootCause = rootCause;
114 }
115
116 /**
117 * Gets the cause of this throwable.
118 *
119 * @return the cause of this throwable, or <code>null</code>
120 */
121 public Throwable getCause()
122 {
123 return rootCause;
124 }
125
126 /**
127 * Prints the stack trace of this exception to the standard error stream.
128 */
129 public void printStackTrace()
130 {
131 printStackTrace(System.err);
132 }
133
134 /**
135 * Prints the stack trace of this exception to the specified stream.
136 *
137 * @param out the <code>PrintStream</code> to use for output
138 */
139 public void printStackTrace(PrintStream out)
140 {
141 synchronized (out)
142 {
143 PrintWriter pw = new PrintWriter(out, false);
144 printStackTrace(pw);
145
146 // Flush the PrintWriter before it's GC'ed.
147 pw.flush();
148 }
149 }
150
151 /**
152 * Prints the stack trace of this exception to the specified writer.
153 *
154 * @param out the <code>PrintWriter</code> to use for output
155 */
156 public void printStackTrace(PrintWriter out)
157 {
158 synchronized (out)
159 {
160 super.printStackTrace(out);
161
162 if (!JDK_SUPPORTS_NESTED && (rootCause != null))
163 {
164 out.print("Caused by: ");
165 rootCause.printStackTrace(out);
166 }
167 }
168 }
169 }