KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > common > exceptions > driver > protocol > SerializableException


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2005 Emic Networks
4  * Contact: c-jdbc@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by the
8  * Free Software Foundation; either version 2.1 of the License, or any later
9  * version.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19  *
20  * Initial developer(s): Marc Herbert
21  * Contributor(s): ______________________.
22  */

23
24 package org.objectweb.cjdbc.common.exceptions.driver.protocol;
25
26 import java.io.IOException JavaDoc;
27 import java.io.PrintStream JavaDoc;
28 import java.io.PrintWriter JavaDoc;
29
30 import org.objectweb.cjdbc.common.stream.CJDBCInputStream;
31 import org.objectweb.cjdbc.common.stream.CJDBCOutputStream;
32
33 /**
34  * This class implements our own Exception chain, overriding Throwable as much
35  * as possible, relying on our own SerializableStackTraceElement instead of
36  * java.lang.StackStraceElement.
37  * <p>
38  * The main reason for this class is that java.lang.StackStraceElement is not
39  * serializable in JDK 1.4 (the constructor is missing, whereas 1.5 has it).
40  * Unfortunately we cannot override everything we would like to because
41  * StackTraceElement is also final and so SerializableStackTraceElement cannot
42  * subtype+override it.
43  *
44  * @author <a HREF="mailto:Marc.Herbert@emicnetworks.com">Marc Herbert</a>
45  * @version 1.0
46  */

47 public class SerializableException
48     extends Exception JavaDoc
49 {
50
51   private String JavaDoc sqlState;
52   private int vendorCode;
53
54   private SerializableStackTraceElement[] stackTrace;
55
56   /**
57    * @see Exception#Exception(java.lang.Throwable)
58    */

59   SerializableException(String JavaDoc message, SerializableException cause)
60   {
61     super(message, cause);
62   }
63
64   /**
65    * Converts a chain of Throwables to a chain of
66    * <code>SerializableException</code>. The resulting chain has the same
67    * length.
68    *
69    * @param start head of chain to convert
70    */

71
72   SerializableException(Throwable JavaDoc start)
73   {
74     this(start.getMessage(), null == start.getCause()
75         ? null
76         : new SerializableException(start.getCause())); // recursion
77

78     convertStackTrace(start);
79   }
80
81   void convertStackTrace(Throwable JavaDoc regularEx)
82   {
83     StackTraceElement JavaDoc[] regularST = regularEx.getStackTrace();
84     stackTrace = new SerializableStackTraceElement[regularST.length];
85     for (int i = 0; i < regularST.length; i++)
86       stackTrace[i] = new SerializableStackTraceElement(regularST[i]);
87
88     // nullifies super's, non-serializable stack trace since we don't want to
89
// use it anymore
90
setStackTrace(null /* ignored arg */);
91
92   }
93
94   /* ***** Serialization / Networking ********* */
95
96   /**
97    * Constructs/reads a new SerializableException chain from the stream
98    */

99   SerializableException(CJDBCInputStream in) throws IOException JavaDoc
100   {
101     // receive message and next exception (recursive)
102
// (left to right evaluation is guaranteed by JLS bible)
103
super(in.readUTF(), in.readBoolean() ? new SerializableException(in) : null);
104
105     // receive stackTrace
106
stackTrace = new SerializableStackTraceElement[in.readInt()];
107     for (int i = 0; i < stackTrace.length; i++)
108       stackTrace[i] = new SerializableStackTraceElement(in);
109
110     // receive SQL fields
111
setSQLState(in.readUTF());
112     setErrorCode(in.readInt());
113
114   }
115
116   /**
117    * Send the Serializable chain to the given stream.
118    *
119    * @param out destination stream
120    * @throws IOException stream error
121    */

122   public void sendToStream(CJDBCOutputStream out) throws IOException JavaDoc
123   {
124     // send message
125
out.writeUTF(getMessage());
126
127     // send next exception if any (chaining)
128
if (null != getCause())
129     {
130       out.writeBoolean(true);
131       ((SerializableException) getCause()).sendToStream(out); // recursion
132
}
133     else
134       out.writeBoolean(false); // stop condition
135

136     // send stack trace
137
out.writeInt(stackTrace.length);
138     for (int i = 0; i < stackTrace.length; i++)
139       stackTrace[i].sendToStream(out);
140
141     // send SQL fields
142
out.writeUTF(getSQLState());
143     out.writeInt(getErrorCode());
144
145     out.flush();
146   }
147
148   /**
149    * @see java.lang.Throwable#printStackTrace()
150    */

151   public void printStackTrace()
152   {
153     printStackTrace(System.err);
154   }
155
156   /**
157    * Prints this throwable and its backtrace to the specified print stream.
158    *
159    * @param s <code>PrintStream</code> to use for output
160    */

161   public void printStackTrace(PrintStream JavaDoc s)
162   {
163     synchronized (s)
164     {
165       s.println(this);
166       for (int i = 0; i < stackTrace.length; i++)
167         s.println("\tAt: " + stackTrace[i]);
168
169       SerializableException ourCause = (SerializableException) getCause();
170       if (ourCause != null)
171       {
172         s.println("Caused by");
173         ourCause.printStackTrace(s);
174       }
175     }
176   }
177
178   /**
179    * Prints this throwable and its backtrace to the specified print writer.
180    *
181    * @param s <code>PrintWriter</code> to use for output
182    */

183   public void printStackTrace(PrintWriter JavaDoc s)
184   {
185     synchronized (s)
186     {
187       s.println(this);
188       for (int i = 0; i < stackTrace.length; i++)
189         s.println("\tAt: " + stackTrace[i]);
190
191       SerializableException ourCause = (SerializableException) getCause();
192       if (ourCause != null)
193       {
194         s.println("Caused by");
195         ourCause.printStackTrace(s);
196       }
197     }
198   }
199
200
201   /**
202    * @deprecated
203    * @see java.lang.Throwable#fillInStackTrace()
204    */

205   public synchronized Throwable JavaDoc fillInStackTrace()
206   {
207     setStackTrace(null);
208     return this;
209   }
210
211   /**
212    * Please use getSerializedStackTrace() instead. Unfortunately
213    * StackTraceElement has no constructor in 1.4 and cannot be overriden
214    * (final).
215    *
216    * @deprecated
217    * @see java.lang.Throwable#getStackTrace()
218    */

219   public StackTraceElement JavaDoc[] getStackTrace()
220   {
221     return new StackTraceElement JavaDoc[0];
222   }
223
224   /**
225    * Returns our private stack trace, the one which is serializable.
226    *
227    * @return our private stack trace
228    */

229   public SerializableStackTraceElement[] getSerializableStackTrace()
230   {
231     return (SerializableStackTraceElement[]) stackTrace.clone();
232   }
233
234   /**
235    * This method is deprecated and erases the regular, non serializable stack
236    * trace. Please use setSerializedStackTrace() instead. Unfortunately
237    * StackTraceElement has no constructor in 1.4 and cannot be overriden
238    * (final).
239    *
240    * @deprecated
241    * @see java.lang.Throwable#setStackTrace(java.lang.StackTraceElement[])
242    */

243   public void setStackTrace(StackTraceElement JavaDoc[] ignored)
244   {
245     super.setStackTrace(new StackTraceElement JavaDoc[0]);
246   }
247
248   /**
249    * Sets the vendorCode value.
250    *
251    * @param vendorCode The vendorCode to set.
252    */

253   void setErrorCode(int vendorCode)
254   {
255     this.vendorCode = vendorCode;
256   }
257
258   /**
259    * Returns the vendorCode value.
260    *
261    * @return Returns the vendorCode.
262    */

263   public int getErrorCode()
264   {
265     return vendorCode;
266   }
267
268   /**
269    * Sets the sQLState value.
270    *
271    * @param sQLState The sQLState to set.
272    */

273   public void setSQLState(String JavaDoc sQLState)
274   {
275     this.sqlState = sQLState;
276   }
277
278   /**
279    * Returns the sQLState value.
280    *
281    * @return Returns the sQLState.
282    */

283   public String JavaDoc getSQLState()
284   {
285     return sqlState;
286   }
287
288   /**
289    * Override super, adding an extra check because we do not want a mixed chain.
290    *
291    * @see java.lang.Throwable#initCause(java.lang.Throwable)
292    */

293   public Throwable JavaDoc initCause(Throwable JavaDoc cause)
294   {
295     throwsIfNotSerializable(cause);
296
297     super.initCause(cause);
298     return this;
299   }
300
301   private void throwsIfNotSerializable(Throwable JavaDoc cause)
302       throws IllegalArgumentException JavaDoc
303   {
304     if (null == cause)
305       return;
306
307     if (!(cause instanceof SerializableException))
308       throw new IllegalArgumentException JavaDoc(
309           "The cause of SerializableException has to be a SerializableException");
310   }
311
312 }
313
Popular Tags