001 /*
002 *
003 * $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
004 *
005 * This file is part of *** M y C o R e ***
006 * See http://www.mycore.de/ for details.
007 *
008 * This program is free software; you can use it, redistribute it
009 * and / or modify it under the terms of the GNU General Public License
010 * (GPL) as published by the Free Software Foundation; either version 2
011 * of the License or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program, in a file called gpl.txt or license.txt.
020 * If not, write to the Free Software Foundation Inc.,
021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
022 */
023
024 package org.mycore.common;
025
026 import java.io.ByteArrayOutputStream;
027 import java.io.PrintStream;
028
029 /**
030 * Instances of this class represent a general exception thrown by any part of
031 * the MyCoRe implementation classes.
032 *
033 * @author Jens Kupferschmidt
034 * @author Frank Lützenkirchen
035 * @version $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
036 *
037 * @see RuntimeException
038 */
039 public class MCRException extends RuntimeException {
040 /** the embedded exception that was thrown by an underlying system */
041 protected Exception exception;
042
043 /**
044 * Creates a new MCRException with an error message
045 *
046 * @param message
047 * the error message for this exception
048 */
049 public MCRException(String message) {
050 super(message);
051 }
052
053 /**
054 * Creates a new MCRException with an error message and a reference to an
055 * exception thrown by an underlying system. Normally, this exception will
056 * be the cause why we would throw an MCRException, e. g. when something in
057 * the datastore goes wrong.
058 *
059 * @param message
060 * the error message for this exception
061 * @param exception
062 * the exception that was thrown by an underlying system
063 */
064 public MCRException(String message, Exception exception) {
065 this(message);
066 this.exception = exception;
067 }
068
069 /**
070 * Returns the exception thrown by an underlying system
071 *
072 * @return the exception thrown by an underlying system
073 */
074 public Exception getException() {
075 return exception;
076 }
077
078 /**
079 * Returns a String containing the invocation stack trace for this exception
080 *
081 * @return a String containing the invocation stack trace for this exception
082 */
083 public String getStackTraceAsString() {
084 return getStackTraceAsString(this);
085 }
086
087 /**
088 * Returns a String containing the invocation stack trace of an exception
089 *
090 * @param ex
091 * the exception you want the stack trace of
092 * @return the invocation stack trace of an exception
093 */
094 public static String getStackTraceAsString(Throwable ex) {
095 // We let Java print the stack trace to a buffer in memory to be able to
096 // get it as String:
097 ByteArrayOutputStream baos = new ByteArrayOutputStream();
098
099 try {
100 PrintStream buffer = new PrintStream(baos);
101 ex.printStackTrace(buffer);
102 buffer.close();
103 } catch (Exception willNeverBeThrown) {
104 }
105
106 return baos.toString();
107 }
108
109 /** Counter to prevent a recursion between getStackTrace() and toString() */
110 private int toStringInvocationCounter = 0;
111
112 /**
113 * Returns a String representation of this exception and all its properties
114 *
115 * @return a String representation of this exception and all its properties
116 */
117 public synchronized String toString() {
118 // Use counter to prevent a recursion between getStackTrace() and
119 // toString()
120 toStringInvocationCounter++;
121
122 if (toStringInvocationCounter > 1) {
123 return super.toString();
124 }
125
126 StringBuffer sb = new StringBuffer();
127
128 sb.append("MyCoRe Exception: ").append(getClass().getName());
129 sb.append("\n\n");
130 sb.append("Message:\n");
131 sb.append(getMessage()).append("\n\n");
132 sb.append("Stack trace:\n");
133 sb.append(getStackTraceAsString());
134
135 if (exception != null) {
136 sb.append("\n");
137 sb.append("This exception was thrown because of the following underlying exception:\n\n");
138 sb.append(exception.getClass().getName());
139 sb.append("\n\n");
140
141 String msg = exception.getLocalizedMessage();
142
143 if (msg != null) {
144 sb.append("Message:\n").append(msg).append("\n\n");
145 }
146
147 sb.append("Stack trace:\n");
148 sb.append(getStackTraceAsString(exception));
149 }
150
151 toStringInvocationCounter--;
152
153 return sb.toString();
154 }
155 }