KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > common > exceptions > driver > protocol > SerializableException


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2005 Emic Networks
4  * Contact: sequoia@continuent.org
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Initial developer(s): Marc Herbert
19  * Contributor(s): ______________________.
20  */

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

45 public class SerializableException extends Exception JavaDoc
46 {
47   private static final long serialVersionUID = -7676999309139924676L;
48
49   private String JavaDoc sqlState;
50   private int vendorCode;
51
52   private SerializableStackTraceElement[] stackTrace;
53
54   /**
55    * @see Exception#Exception(java.lang.Throwable)
56    */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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