blob: f1e0adf3dce9f85920d415eca7f5fcbfc4218e55 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
<<<<<<< Updated upstream
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
=======
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
>>>>>>> Stashed changes
* limitations under the License.
*/
/*
* JDOException.java
*
*/
package javax.jdo;
import javax.jdo.spi.I18NHelper;
/**
* This is the root of all JDO Exceptions. It contains an optional detail message, an optional
* nested <code>Throwable</code> array and an optional failed object.
*
* @author Craig Russell
* @version 1.0.2
*/
public class JDOException extends java.lang.RuntimeException {
private static final long serialVersionUID = 1950979275859696534L;
/**
* This exception was generated because of an exception in the runtime library.
*
* @serial the nested <code>Throwable</code> array
*/
Throwable[] nested;
/**
* This exception may be the result of incorrect parameters supplied to an API. This is the object
* from which the user can determine the cause of the problem.
*
* @serial the failed <code>Object</code>
*/
Object failed;
/** The Internationalization message helper. */
private static final I18NHelper MSG = I18NHelper.getInstance("javax.jdo.Bundle"); // NOI18N
/** Flag indicating whether printStackTrace is being executed. */
private boolean inPrintStackTrace = false;
/** Constructs a new <code>JDOException</code> without a detail message. */
public JDOException() {}
/**
* Constructs a new <code>JDOException</code> with the specified detail message.
*
* @param msg the detail message.
*/
public JDOException(String msg) {
super(msg);
}
/**
* Constructs a new <code>JDOException</code> with the specified detail message and nested <code>
* Throwable</code>s.
*
* @param msg the detail message.
* @param nested the nested <code>Throwable[]</code>.
*/
public JDOException(String msg, Throwable[] nested) {
super(msg);
this.nested = nested;
}
/**
* Constructs a new <code>JDOException</code> with the specified detail message and nested <code>
* Throwable</code>.
*
* @param msg the detail message.
* @param nested the nested <code>Throwable</code>.
*/
public JDOException(String msg, Throwable nested) {
super(msg);
this.nested = new Throwable[] {nested};
}
/**
* Constructs a new <code>JDOException</code> with the specified detail message and failed object.
*
* @param msg the detail message.
* @param failed the failed object.
*/
public JDOException(String msg, Object failed) {
super(msg);
this.failed = failed;
}
/**
* Constructs a new <code>JDOException</code> with the specified detail message, nested <code>
* Throwable</code>s, and failed object.
*
* @param msg the detail message.
* @param nested the nested <code>Throwable[]</code>.
* @param failed the failed object.
*/
public JDOException(String msg, Throwable[] nested, Object failed) {
super(msg);
this.nested = nested;
this.failed = failed;
}
/**
* Constructs a new <code>JDOException</code> with the specified detail message, nested <code>
* Throwable</code>, and failed object.
*
* @param msg the detail message.
* @param nested the nested <code>Throwable</code>.
* @param failed the failed object.
*/
public JDOException(String msg, Throwable nested, Object failed) {
super(msg);
this.nested = new Throwable[] {nested};
this.failed = failed;
}
/**
* The exception may include a failed object.
*
* @return the failed object.
*/
public Object getFailedObject() {
return failed;
}
/**
* The exception may have been caused by multiple exceptions in the runtime. If multiple objects
* caused the problem, each failed object will have its own <code>Exception</code>.
*
* @return the nested Throwable array.
*/
public Throwable[] getNestedExceptions() {
return nested;
}
/**
* Often there is only one nested exception, and this method returns it. If there are more than
* one, then this method returns the first nested exception. If there is no nested exception, then
* null is returned.
*
* @return the first or only nested Throwable.
* @since 1.0.1
*/
public synchronized Throwable getCause() {
// super.printStackTrace calls getCause to handle the cause.
// Returning null prevents the superclass from handling the cause;
// instead the local implementation of printStackTrace should
// handle the cause. Otherwise, the cause is printed twice.
if (nested == null || nested.length == 0 || inPrintStackTrace) {
return null;
} else {
return nested[0];
}
}
/**
* JDK 1.4 includes a new chaining mechanism for Throwable, but since JDO has its own "legacy"
* chaining mechanism, the "standard" mechanism cannot be used. This method always throws a
* JDOFatalInternalException.
*
* @param cause ignored.
* @return never.
*/
public Throwable initCause(Throwable cause) {
throw new JDOFatalInternalException(MSG.msg("ERR_CannotInitCause"));
}
/**
* The <code>String</code> representation includes the name of the class, the descriptive comment
* (if any), the <code>String</code> representation of the failed <code>Object</code> (if any),
* and the <code>String</code> representation of the nested <code>Throwable</code>s (if any).
*
* @return the <code>String</code>.
*/
public synchronized String toString() {
int len = nested == null ? 0 : nested.length;
// calculate approximate size of the String to return
StringBuffer sb = new StringBuffer(10 + 100 * len);
sb.append(super.toString());
// include failed object information
if (failed != null) {
sb.append("\n").append(MSG.msg("MSG_FailedObject"));
String failedToString = null;
try {
failedToString = failed.toString();
} catch (Exception ex) {
// include the information from the exception thrown by failed.toString
Object objectId = JDOHelper.getObjectId(failed);
if (objectId == null) {
failedToString =
MSG.msg(
"MSG_ExceptionGettingFailedToString", // NOI18N
exceptionToString(ex));
} else {
// include the ObjectId information
String objectIdToString = null;
try {
objectIdToString = objectId.toString();
} catch (Exception ex2) {
objectIdToString = exceptionToString(ex2);
}
failedToString =
MSG.msg(
"MSG_ExceptionGettingFailedToStringObjectId", // NOI18N
exceptionToString(ex),
objectIdToString);
}
}
sb.append(failedToString);
}
// include nested Throwable information, but only if not called by
// printStackTrace; the stacktrace will include the cause anyway.
if (len > 0 && !inPrintStackTrace) {
sb.append("\n").append(MSG.msg("MSG_NestedThrowables")).append("\n");
Throwable exception = nested[0];
sb.append(exception == null ? "null" : exception.toString()); // NOI18N
for (int i = 1; i < len; ++i) {
sb.append("\n"); // NOI18N
exception = nested[i];
sb.append(exception == null ? "null" : exception.toString()); // NOI18N
}
}
return sb.toString();
}
/**
* Prints this <code>JDOException</code> and its backtrace to the standard error output. Print
* nested Throwables' stack trace as well.
*/
public void printStackTrace() {
printStackTrace(System.err);
}
/**
* Prints this <code>JDOException</code> and its backtrace to the specified print stream. Print
* nested Throwables' stack trace as well.
*
* @param s <code>PrintStream</code> to use for output
*/
public synchronized void printStackTrace(java.io.PrintStream s) {
int len = nested == null ? 0 : nested.length;
synchronized (s) {
inPrintStackTrace = true;
super.printStackTrace(s);
if (len > 0) {
s.println(MSG.msg("MSG_NestedThrowablesStackTrace"));
for (int i = 0; i < len; ++i) {
Throwable exception = nested[i];
if (exception != null) {
exception.printStackTrace(s);
}
}
}
inPrintStackTrace = false;
}
}
/**
* Prints this <code>JDOException</code> and its backtrace to the specified print writer. Print
* nested Throwables' stack trace as well.
*
* @param s <code>PrintWriter</code> to use for output
*/
public synchronized void printStackTrace(java.io.PrintWriter s) {
int len = nested == null ? 0 : nested.length;
synchronized (s) {
inPrintStackTrace = true;
super.printStackTrace(s);
if (len > 0) {
s.println(MSG.msg("MSG_NestedThrowablesStackTrace"));
for (int i = 0; i < len; ++i) {
Throwable exception = nested[i];
if (exception != null) {
exception.printStackTrace(s);
}
}
}
inPrintStackTrace = false;
}
}
/**
* Helper method returning a short description of the exception passed as an argument. The
* returned string has the format defined by Throwable.toString. If the exception has a non-null
* detail message string, then it returns the name of exception class concatenated with ": "
* concatenated with the detailed message. Otherwise it returns the name of exception class.
*
* @param ex the exception to be represented.
* @return a string representation of the exception passed as an argument.
*/
private static String exceptionToString(Exception ex) {
if (ex == null) return null;
String s = ex.getClass().getName();
String message = ex.getMessage();
return (message != null) ? (s + ": " + message) : s;
}
}