001: /*
002: * Copyright 2004-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.apache.lucene.store.jdbc;
018:
019: import java.io.IOException;
020: import java.io.PrintStream;
021: import java.io.PrintWriter;
022:
023: /**
024: * A nestable checked Jdbc exception.
025: *
026: * @author kimchy
027: */
028: public class JdbcStoreException extends IOException {
029:
030: private static final long serialVersionUID = 6238846660780283933L;
031:
032: /** Root cause of this nested exception */
033: private Throwable cause;
034:
035: /**
036: * Construct a <code>JdbcStoreException</code> with the specified detail message.
037: * @param msg the detail message
038: */
039: public JdbcStoreException(String msg) {
040: super (msg);
041: }
042:
043: /**
044: * Construct a <code>JdbcStoreException</code> with the specified detail message
045: * and nested exception.
046: * @param msg the detail message
047: * @param ex the nested exception
048: */
049: public JdbcStoreException(String msg, Throwable ex) {
050: super (msg);
051: this .cause = ex;
052: }
053:
054: /**
055: * Return the nested cause, or <code>null</code> if none.
056: */
057: public Throwable getCause() {
058: // Even if you cannot set the cause of this exception other than through
059: // the constructor, we check for the cause being "this" here, as the cause
060: // could still be set to "this" via reflection: for example, by a remoting
061: // deserializer like Hessian's.
062: return (this .cause == this ? null : this .cause);
063: }
064:
065: /**
066: * Return the detail message, including the message from the nested exception
067: * if there is one.
068: */
069: public String getMessage() {
070: if (getCause() == null) {
071: return super .getMessage();
072: } else {
073: return super .getMessage() + "; nested exception is "
074: + getCause().getClass().getName() + ": "
075: + getCause().getMessage();
076: }
077: }
078:
079: /**
080: * Print the composite message and the embedded stack trace to the specified stream.
081: * @param ps the print stream
082: */
083: public void printStackTrace(PrintStream ps) {
084: if (getCause() == null) {
085: super .printStackTrace(ps);
086: } else {
087: ps.println(this );
088: getCause().printStackTrace(ps);
089: }
090: }
091:
092: /**
093: * Print the composite message and the embedded stack trace to the specified print writer.
094: * @param pw the print writer
095: */
096: public void printStackTrace(PrintWriter pw) {
097: if (getCause() == null) {
098: super .printStackTrace(pw);
099: } else {
100: pw.println(this );
101: getCause().printStackTrace(pw);
102: }
103: }
104:
105: /**
106: * Check whether this exception contains an exception of the given class:
107: * either it is of the given class itself or it contains a nested cause
108: * of the given class.
109: * <p>Currently just traverses JdbcStoreException causes. Will use
110: * the JDK 1.4 exception cause mechanism once requires JDK 1.4.
111: * @param exClass the exception class to look for
112: */
113: public boolean contains(Class exClass) {
114: if (exClass == null) {
115: return false;
116: }
117: Throwable ex = this ;
118: while (ex != null) {
119: if (exClass.isInstance(ex)) {
120: return true;
121: }
122: if (ex instanceof JdbcStoreException) {
123: // Cast is necessary on JDK 1.3, where Throwable does not
124: // provide a "getCause" method itself.
125: ex = ex.getCause();
126: } else {
127: ex = null;
128: }
129: }
130: return false;
131: }
132:
133: }
|