001: /*
002: * Copyright 2002-2006 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.web.util;
018:
019: import java.io.PrintStream;
020: import java.io.PrintWriter;
021:
022: import javax.servlet.ServletException;
023:
024: import org.springframework.core.NestedExceptionUtils;
025:
026: /**
027: * Subclass of ServletException that properly handles a root cause in terms
028: * of message and stacktrace, just like NestedChecked/RuntimeException does.
029: * Note that the plain ServletException doesn't expose its root cause at all,
030: * neither in the exception message nor in printed stack traces!
031: *
032: * <p>The similarity between this class and the NestedChecked/RuntimeException
033: * class is unavoidable, as this class needs to derive from ServletException
034: * and cannot derive from NestedCheckedException.
035: *
036: * @author Juergen Hoeller
037: * @since 1.2.5
038: * @see #getMessage
039: * @see #printStackTrace
040: * @see org.springframework.core.NestedCheckedException
041: * @see org.springframework.core.NestedRuntimeException
042: */
043: public class NestedServletException extends ServletException {
044:
045: /** Use serialVersionUID from Spring 1.2 for interoperability */
046: private static final long serialVersionUID = -5292377985529381145L;
047:
048: /**
049: * Construct a <code>NestedServletException</code> with the specified detail message.
050: * @param msg the detail message
051: */
052: public NestedServletException(String msg) {
053: super (msg);
054: }
055:
056: /**
057: * Construct a <code>NestedServletException</code> with the specified detail message
058: * and nested exception.
059: * @param msg the detail message
060: * @param cause the nested exception
061: */
062: public NestedServletException(String msg, Throwable cause) {
063: super (msg, cause);
064: }
065:
066: /**
067: * Return the detail message, including the message from the nested exception
068: * if there is one.
069: */
070: public String getMessage() {
071: return NestedExceptionUtils.buildMessage(super .getMessage(),
072: getRootCause());
073: }
074:
075: /**
076: * Print the composite message and the embedded stack trace to the specified stream.
077: * @param ps the print stream
078: */
079: public void printStackTrace(PrintStream ps) {
080: Throwable cause = getRootCause();
081: if (cause == null) {
082: super .printStackTrace(ps);
083: } else {
084: ps.println(this );
085: ps.print("Caused by: ");
086: cause.printStackTrace(ps);
087: }
088: }
089:
090: /**
091: * Print the composite message and the embedded stack trace to the specified print writer.
092: * @param pw the print writer
093: */
094: public void printStackTrace(PrintWriter pw) {
095: Throwable cause = getRootCause();
096: if (cause == null) {
097: super .printStackTrace(pw);
098: } else {
099: pw.println(this );
100: pw.print("Caused by: ");
101: cause.printStackTrace(pw);
102: }
103: }
104:
105: }
|