001: /*
002: * ThrowableList.java: Interface for throwable stacks
003: *
004: * Copyright (C) 2002 Heiko Blau
005: *
006: * This file belongs to the Susebox Java Core Library (Susebox JCL).
007: * The Susebox JCL is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as published by the
009: * Free Software Foundation; either version 2.1 of the License, or (at your
010: * option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE.
015: * See the GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License along
018: * with the Susebox JCL. If not, write to the
019: *
020: * Free Software Foundation, Inc.
021: * 59 Temple Place, Suite 330,
022: * Boston, MA 02111-1307
023: * USA
024: *
025: * or check the Internet: http://www.fsf.org
026: *
027: * Contact:
028: * email: heiko@susebox.de
029: */
030:
031: package de.susebox.java.lang;
032:
033: //------------------------------------------------------------------------------
034: // Imports
035: //
036:
037: /*-->
038: import de.susebox.java.lang.ThrowableList;
039: import de.susebox.java.lang.ThrowableMessageFormatter;
040: -->*/
041:
042: //------------------------------------------------------------------------------
043: // Interface ThrowableList
044: //
045: /**<p>
046: * This interface should be implemented by classes derived from {@link java.lang.Throwable}
047: * that may contain a stacked, additional or wrapped throwable.
048: *</p><p>
049: * Such cases are common when
050: *<ul><li>
051: * a method implements a certain interface method that allows for a specific
052: * throwable like IOException, but the method itself may encounter a different
053: * throwable type like SQLException (wrapped throwable)
054: *</li><li>
055: * one application layer catches an throwable only to add its specific
056: * information in form of another throwable (throwable stack, nested throwable
057: * like in SQLException or MessagingException).
058: *</li></ul>
059: *</p><p>
060: * We provide the expected code in block comments starting with -->, terminated
061: * by -->. Note that the provided code also includes a new implementation of
062: * the base class method {@link java.lang.Throwable#getMessage} using the text
063: * formatting capabilities of {@link java.text.MessageFormat}.
064: *<p></p>
065: * <strong>Note:</strong> This interface replaces the formerly used <code>ExceptionList</code>
066: * interface.
067: *<p></p>
068: * <strong>Note:</strong> With JDK 1.4, the <i>chained exception facility</i>
069: * is available, that implements a Throwable stack (or list of causes) already
070: * in {@link java.lang.Throwable}. Still, the notion of a wrapped exception and
071: * the delayed formatting is a reason for this interface.
072: *</p>
073: *
074: * @version 1.00, 2001/06/26
075: * @author Heiko Blau
076: */
077: public interface ThrowableList {
078:
079: /**
080: * Retrieving the cause of a <code>Throwable</code>. This is the method introduced
081: * with JDK 1.4. It replaces the older {@link #nextThrowable}.
082: *
083: * @return the cause of this <code>Throwable</code>
084: * @see java.lang.Throwable#getCause
085: */
086: public Throwable getCause();
087:
088: /**
089: * Method to traverse the throwable list. By convention, <code>nextThrowable</code>>
090: * returns the "earlier" throwable. By walking down the throwable list one gets the
091: * the following meaning:
092: *<br>
093: * this happened because nextThrowable happened because nextThrowable happened...
094: *<br>
095: * The next throwable has usually one of the following meaning:
096: *<br><ul><li>
097: * It is the "real" throwable. An interface implementation might be allowed to
098: * throw only <code>IOException</code>, but actually has to pass on a
099: * <code>SQLException</code>. That could be done by wrapping the <code>SQLException</code>
100: * into the <code>IOException</code>.
101: *</li><li>
102: * The next throwable is "deeper" cause of this one (often called a nested
103: * throwable). A file couldn't be read in the first place and therefore not be
104: * attached to a mail. Both this throwable and the one nested inside have their
105: * own message.
106: *</li></li>
107: * There are more than one basic throwable to be propagated. A simple parser
108: * might return all syntax errors in one throwable list.
109: *</li></ul>
110: *
111: * @return the "earlier" throwable
112: * @deprecated use the JDK 1.4 call {@link #getCause} instead
113: */
114: public Throwable nextThrowable();
115:
116: /*-->
117: {
118: return _next;
119: }
120: -->*/
121:
122: /**
123: * Check if <code>this</code> is only a throwable that wraps the real one. This
124: * might be nessecary to pass an throwable incompatible to a method declaration.
125: *
126: * @return <code>true</code> if this is a wrapper throwable,
127: * <code>false</code> otherwise
128: */
129: public boolean isWrapper();
130:
131: /*-->
132: {
133: return _isWrapper;
134: }
135: -->*/
136:
137: /**
138: * Getting the format string of a throwable message. This can also be the
139: * message itself if there are no arguments.
140: *
141: * @return the format string being used by {@link java.text.MessageFormat}
142: * @see #getArguments
143: */
144: public String getFormat();
145:
146: /*-->
147: {
148: return super.getMessage();
149: }
150: -->*/
151:
152: /**
153: * Retrieving the arguments for message formats. These arguments are used by
154: * the {@link java.text.MessageFormat#format} call.
155: *
156: * @return the arguments for a message format
157: * @see #getFormat
158: */
159: public Object[] getArguments();
160: /*-->
161: {
162: return _args;
163: }
164: -->*/
165:
166: //---------------------------------------------------------------------------
167: // implementation code templates
168: //
169: /**
170: * This constructor takes a simple message string like ordinary Java
171: * {@link java.lang.Throwable} classes. This is the most convenient form to
172: * construct an <code>ThrowableList</code> throwable.
173: *
174: * @param msg message for this <code>Throwable</code> instance
175: */
176: /*-->
177: public <<WHICH>>Throwable(String msg) {
178: this(null, msg, null);
179: }
180: -->*/
181:
182: /**
183: * This constructor should be used for wrapping another {@link java.lang.Throwable}.
184: * While reading data an <code>IOException</code> may occur, but a certain interface
185: * requires a <code>SQLException</code>. Simply use:
186: *<blockquote><pre>
187: * try {
188: * ...
189: * } catch (NullPointerException ex) {
190: * throw new ExtNoSuchMethodException(ex);
191: * }
192: *</pre></blockquote>
193: *
194: * @param trowable the <code>Throwable</code> to wrap
195: */
196: /*-->
197: public <<WHICH>>Throwable(Throwable throwable) {
198: this(throwable, null, null);
199: }
200: -->*/
201:
202: /**
203: * If one likes to add ones own information to an throwable, this constructor is
204: * the easiest way to do so. By using such an approach a throwable trace with useful
205: * additional informations (which file could be found, what username is unknown)
206: * can be realized:
207: *<blockquote><pre>
208: * try {
209: * ...
210: * } catch (SQLException ex) {
211: * throw new MyException(ex, "while connecting to " + url);
212: * }
213: *</pre></blockquote>
214: *
215: * @param throwable the inner throwable
216: * @param msg throwable message
217: */
218: /*-->
219: public <<WHICH>>Throwable(Throwable throwable, String msg) {
220: this(throwable, msg, null);
221: }
222: -->*/
223:
224: /**
225: * This constructor takes a format string and its arguments. The format string
226: * must have a form that can be used by {@link java.text.MessageFormat} methods.
227: * That means:
228: *<blockquote><pre>
229: * java.text.Message.format(fmt, args)
230: *</pre></blockquote>
231: * is similar to
232: *<blockquote><pre>
233: * new MyException(fmt, args).getMessage();
234: *</pre></blockquote>
235: *
236: * @param fmt throwable message format
237: * @param args arguments for the given format string
238: */
239: /*-->
240: public <<WHICH>>Throwable(String fmt, Object[] args) {
241: this(null, msg, args);
242: }
243: -->*/
244:
245: /**
246: * This is the most complex way to construct an <code>ThrowableList</code>-
247: * Throwable.<br>
248: * An inner throwable is accompanied by a format string and its arguments.
249: * Use this constructor in language-sensitive contexts or for formalized messages.
250: * The meaning of the parameters is explained in the other constructors.
251: *
252: * @param throwable the inner throwable
253: * @param fmt throwable message
254: * @param args arguments for the given format string
255: */
256: /*-->
257: public <<WHICH>>Throwable(Throwable throwable, String fmt, Object[] args) {
258: super(fmt);
259:
260: if (throwable != null && fmt == null) {
261: _isWrapper = true;
262: } else {
263: _isWrapper = false;
264: }
265: _next = throwable;
266: _args = args;
267: }
268: -->
269:
270: /**
271: * Implementation of the standard {@link java.lang.Throwable#getMessage} method to
272: * meet the requirements of formats and format arguments as well as wrapper
273: * exceptions.<br>
274: * If this is a wrapper throwable then the <code>getMessage</code> of the wrapped
275: * throwable is returned.<br>
276: * If this is not a wrapper throwable: if no arguments were given in the
277: * constructor then the format parameter is taken as the formatted message itself.
278: * Otherwise it is treated like the patter for the {@link java.text.MessageFormat#format}
279: * method.
280: *
281: * @return the formatted throwable message
282: * @see java.text.MessageFormat
283: */
284: /*-->
285: public String getMessage() {
286: return ThrowableMessageFormatter.getMessage(this);
287: }
288: -->*/
289:
290: //---------------------------------------------------------------------------
291: // members
292: //
293: /**
294: * the parameters to be used when formatting the throwable message
295: */
296: /*-->
297: protected Object[] _args = null;
298: -->*/
299:
300: /**
301: * The wrapped, nested of next throwable.
302: */
303: /*-->
304: protected Throwable _next = null;
305: -->*/
306:
307: /**
308: * If <code>true</code> this is only a wrapper throwable with the real one
309: * being returned by {@link #nextThrowable}, <code>false</code> for standalone,
310: * nested or subsequent exceptions
311: */
312: /*-->
313: protected boolean _isWrapper = false;
314: -->*/
315: }
|