1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package javax.jdo;
23
24 import javax.jdo.spi.I18NHelper;
25
26 /*** This is the root of all JDO Exceptions. It contains an optional detail
27 * message, an optional nested <code>Throwable</code> array and an optional failed object.
28 * @author Craig Russell
29 * @version 1.0.2
30 */
31 public class JDOException extends java.lang.RuntimeException {
32
33 /*** This exception was generated because of an exception in the runtime library.
34 * @serial the nested <code>Throwable</code> array
35 */
36 Throwable[] nested;
37
38 /*** This exception may be the result of incorrect parameters supplied
39 * to an API. This is the object from which the user can determine
40 * the cause of the problem.
41 * @serial the failed <code>Object</code>
42 */
43 Object failed;
44
45 /*** The Internationalization message helper.
46 */
47 private static I18NHelper msg = I18NHelper.getInstance ("javax.jdo.Bundle");
48
49 /*** Flag indicating whether printStackTrace is being executed.
50 */
51 private boolean inPrintStackTrace = false;
52
53 /***
54 * Constructs a new <code>JDOException</code> without a detail message.
55 */
56 public JDOException() {
57 }
58
59
60 /***
61 * Constructs a new <code>JDOException</code> with the specified detail message.
62 * @param msg the detail message.
63 */
64 public JDOException(String msg) {
65 super(msg);
66 }
67
68 /*** Constructs a new <code>JDOException</code> with the specified detail message
69 * and nested <code>Throwable</code>s.
70 * @param msg the detail message.
71 * @param nested the nested <code>Throwable[]</code>.
72 */
73 public JDOException(String msg, Throwable[] nested) {
74 super(msg);
75 this.nested = nested;
76 }
77
78 /*** Constructs a new <code>JDOException</code> with the specified detail message
79 * and nested <code>Throwable</code>.
80 * @param msg the detail message.
81 * @param nested the nested <code>Throwable</code>.
82 */
83 public JDOException(String msg, Throwable nested) {
84 super(msg);
85 this.nested = new Throwable[] {nested};
86 }
87
88 /*** Constructs a new <code>JDOException</code> with the specified detail message
89 * and failed object.
90 * @param msg the detail message.
91 * @param failed the failed object.
92 */
93 public JDOException(String msg, Object failed) {
94 super(msg);
95 this.failed = failed;
96 }
97
98 /*** Constructs a new <code>JDOException</code> with the specified detail message,
99 * nested <code>Throwable</code>s, and failed object.
100 * @param msg the detail message.
101 * @param nested the nested <code>Throwable[]</code>.
102 * @param failed the failed object.
103 */
104 public JDOException(String msg, Throwable[] nested, Object failed) {
105 super(msg);
106 this.nested = nested;
107 this.failed = failed;
108 }
109
110 /*** Constructs a new <code>JDOException</code> with the specified detail message,
111 * nested <code>Throwable</code>, and failed object.
112 * @param msg the detail message.
113 * @param nested the nested <code>Throwable</code>.
114 * @param failed the failed object.
115 */
116 public JDOException(String msg, Throwable nested, Object failed) {
117 super(msg);
118 this.nested = new Throwable[] {nested};
119 this.failed = failed;
120 }
121
122 /*** The exception may include a failed object.
123 * @return the failed object.
124 */
125 public Object getFailedObject() {
126 return failed;
127 }
128
129 /*** The exception may have been caused by multiple exceptions in the runtime.
130 * If multiple objects caused the problem, each failed object will have
131 * its own <code>Exception</code>.
132 * @return the nested Throwable array.
133 */
134 public Throwable[] getNestedExceptions() {
135 return nested;
136 }
137
138 /*** Often there is only one nested exception, and this method returns it.
139 * If there are more than one, then this method returns the first nested
140 * exception. If there is no nested exception, then null is returned.
141 * @return the first or only nested Throwable.
142 * @since 1.0.1
143 */
144 public synchronized Throwable getCause() {
145
146
147
148
149 if (nested == null || nested.length == 0 || inPrintStackTrace) {
150 return null;
151 } else {
152 return nested[0];
153 }
154 }
155
156 /*** JDK 1.4 includes a new chaining mechanism for Throwable, but since
157 * JDO has its own "legacy" chaining mechanism, the "standard" mechanism
158 * cannot be used. This method always throws a JDOFatalInternalException.
159 * @param cause ignored.
160 * @return never.
161 */
162 public Throwable initCause(Throwable cause) {
163 throw new JDOFatalInternalException(msg.msg("ERR_CannotInitCause"));
164 }
165
166 /*** The <code>String</code> representation includes the name of the class,
167 * the descriptive comment (if any),
168 * the <code>String</code> representation of the failed <code>Object</code> (if any),
169 * and the <code>String</code> representation of the nested <code>Throwable</code>s (if any).
170 * @return the <code>String</code>.
171 */
172 public synchronized String toString() {
173 int len = nested==null?0:nested.length;
174
175 StringBuffer sb = new StringBuffer (10 + 100 * len);
176 sb.append (super.toString());
177
178 if (failed != null) {
179 sb.append ("\n").append (msg.msg ("MSG_FailedObject"));
180 String failedToString = null;
181 try {
182 failedToString = failed.toString();
183 } catch (Exception ex) {
184
185 Object objectId = JDOHelper.getObjectId(failed);
186 if (objectId == null) {
187 failedToString = msg.msg("MSG_ExceptionGettingFailedToString",
188 exceptionToString(ex));
189 }
190 else {
191
192 String objectIdToString = null;
193 try {
194 objectIdToString = objectId.toString();
195 }
196 catch (Exception ex2) {
197 objectIdToString = exceptionToString(ex2);
198 }
199 failedToString = msg.msg("MSG_ExceptionGettingFailedToStringObjectId",
200 exceptionToString(ex), objectIdToString);
201 }
202 }
203 sb.append (failedToString);
204 }
205
206
207 if (len > 0 && !inPrintStackTrace) {
208 sb.append ("\n").append (msg.msg ("MSG_NestedThrowables")).append ("\n");
209 Throwable exception = nested[0];
210 sb.append (exception==null?"null":exception.toString());
211 for (int i=1; i<len; ++i) {
212 sb.append ("\n");
213 exception = nested[i];
214 sb.append (exception==null?"null":exception.toString());
215 }
216 }
217 return sb.toString();
218 }
219
220 /***
221 * Prints this <code>JDOException</code> and its backtrace to the
222 * standard error output.
223 * Print nested Throwables' stack trace as well.
224 */
225 public void printStackTrace() {
226 printStackTrace (System.err);
227 }
228
229 /***
230 * Prints this <code>JDOException</code> and its backtrace to the
231 * specified print stream.
232 * Print nested Throwables' stack trace as well.
233 * @param s <code>PrintStream</code> to use for output
234 */
235 public synchronized void printStackTrace(java.io.PrintStream s) {
236 int len = nested==null?0:nested.length;
237 synchronized (s) {
238 inPrintStackTrace = true;
239 super.printStackTrace(s);
240 if (len > 0) {
241 s.println (msg.msg ("MSG_NestedThrowablesStackTrace"));
242 for (int i=0; i<len; ++i) {
243 Throwable exception = nested[i];
244 if (exception != null) {
245 exception.printStackTrace(s);
246 }
247 }
248 }
249 inPrintStackTrace = false;
250 }
251 }
252
253 /***
254 * Prints this <code>JDOException</code> and its backtrace to the specified
255 * print writer.
256 * Print nested Throwables' stack trace as well.
257 * @param s <code>PrintWriter</code> to use for output
258 */
259 public synchronized void printStackTrace(java.io.PrintWriter s) {
260 int len = nested==null?0:nested.length;
261 synchronized (s) {
262 inPrintStackTrace = true;
263 super.printStackTrace(s);
264 if (len > 0) {
265 s.println (msg.msg ("MSG_NestedThrowablesStackTrace"));
266 for (int i=0; i<len; ++i) {
267 Throwable exception = nested[i];
268 if (exception != null) {
269 exception.printStackTrace(s);
270 }
271 }
272 }
273 inPrintStackTrace = false;
274 }
275 }
276
277 /***
278 * Helper method returning a short description of the exception passed
279 * as an argument. The returned string has the format defined by
280 * Throwable.toString. If the exception has a non-null detail message
281 * string, then it returns the name of exception class concatenated
282 * with ": " concatenated with the detailed message. Otherwise it
283 * returns the name of exception class.
284 * @param ex the exception to be represented.
285 * @return a string representation of the exception passed as an argument.
286 */
287 private static String exceptionToString(Exception ex)
288 {
289 if (ex == null) return null;
290 String s = ex.getClass().getName();
291 String message = ex.getMessage();
292 return (message != null) ? (s + ": " + message) : s;
293 }
294 }
295