| /* |
| * Copyright 2005 The Apache Software Foundation. |
| * |
| * Licensed 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 |
| * |
| * http://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 |
| * 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 { |
| |
| /** 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 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; |
| } |
| } |
| |