1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.gridsystems.innergrid.kernel;
18
19 import java.io.PrintStream;
20 import java.io.PrintWriter;
21 import java.rmi.RemoteException;
22 import java.text.MessageFormat;
23 import java.util.ArrayList;
24 import java.util.Vector;
25 import java.util.regex.Pattern;
26
27 import javax.xml.namespace.QName;
28
29 import org.apache.axis.AxisFault;
30 import org.apache.axis.Constants;
31 import org.apache.axis.encoding.SerializationContext;
32 import org.apache.axis.utils.JavaUtils;
33 import org.apache.axis.utils.XMLUtils;
34 import org.w3c.dom.DOMException;
35 import org.w3c.dom.Element;
36 import org.w3c.dom.Node;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class KernelException extends AxisFault implements Kernelizable {
57
58
59
60
61 private static final long serialVersionUID = 1876438763487634L;
62
63
64
65
66 protected String msg;
67
68
69
70
71 protected String pattern;
72
73
74
75
76 protected Object[] params;
77
78
79
80
81
82
83
84
85
86
87 public KernelException(String code, String pattern, Object[] params, Throwable cause) {
88 this(cause, new QName("Kernel", code), pattern, params);
89 }
90
91
92
93
94
95
96
97
98
99
100 public KernelException(QName code, String pattern, Object[] params, Throwable cause) {
101 super(null, cause);
102 super.setFaultCode(code);
103 this.pattern = pattern;
104 this.params = params;
105 if (pattern == null) {
106 msg = "";
107 } else {
108 if (params == null) {
109 msg = pattern;
110 } else {
111 msg = MessageFormat.format(pattern, params);
112 }
113 }
114 super.setFaultString(msg);
115 super.setFaultReason(msg);
116 }
117
118
119
120
121
122
123
124
125
126 public KernelException(Throwable cause, String code, String pattern, Object... params) {
127 this(cause, new QName("Kernel", code), pattern, params);
128 }
129
130
131
132
133
134
135
136
137
138 public KernelException(Throwable cause, QName code, String pattern, Object... params) {
139 super(null, cause);
140 super.setFaultCode(code);
141 this.pattern = pattern;
142 this.params = params;
143 if (pattern == null) {
144 msg = "";
145 } else {
146 if (params == null) {
147 msg = pattern;
148 } else {
149 msg = MessageFormat.format(pattern, params);
150 }
151 }
152 super.setFaultString(msg);
153 super.setFaultReason(msg);
154 }
155
156
157
158
159
160
161 public String getCode() {
162 QName code = super.getFaultCode();
163 String local = code.getLocalPart();
164 int pos = local.indexOf('}');
165
166 return local.substring(pos + 1);
167 }
168
169
170
171
172
173
174
175
176 public boolean hasCode(String code) {
177 QName qcode = super.getFaultCode();
178 return qcode.getLocalPart().equals(code);
179 }
180
181
182
183
184
185
186 public String getNamespace() {
187 QName code = super.getFaultCode();
188 return code.getNamespaceURI();
189 }
190
191
192
193
194
195
196 public Object[] getParams() {
197 return this.params;
198 }
199
200
201
202
203
204
205
206
207 @Override public String getMessage() {
208 return this.msg;
209 }
210
211
212
213
214
215
216 public String getPattern() {
217 return this.pattern;
218 }
219
220
221
222
223
224
225
226 @Override public String toString() {
227 return getCode() + ": " + getMessage();
228 }
229
230
231
232
233
234
235
236
237
238 public static KernelException fromRemoteException(RemoteException e) {
239 if (e instanceof KernelException) {
240 return (KernelException)e;
241 }
242
243 if (e instanceof AxisFault) {
244 AxisFault fault = (AxisFault)e;
245 Element[] details = fault.getFaultDetails();
246
247 QName code = null;
248 String pattern = fault.getFaultString();
249 Throwable cause = fault.getCause();
250 Object[] params = null;
251 ArrayList<String> list = new ArrayList<String>();
252
253
254 int count = details == null ? 0 : details.length;
255 for (int i = 0; i < count; i++) {
256 String nodeName = details[i].getLocalName();
257 String nodeText = getTextContent(details[i]);
258
259 if ("KernelException".equals(nodeName) && "true".equals(nodeText)) {
260
261 code = fault.getFaultCode();
262 }
263 if ("parameter".equals(nodeName)) {
264 list.add(nodeText);
265 }
266 if ("pattern".equals(nodeName)) {
267 pattern = nodeText;
268 }
269 }
270
271
272 if (code == null) {
273 log.debug("The exception " + e.getMessage()
274 + " has been wrapped in a UNK000 exception", e);
275 return new KernelException("UNK000", pattern, null, fault);
276 }
277
278
279 params = new String[list.size()];
280 list.toArray(params);
281
282 return new KernelException(code, pattern, params, cause);
283 }
284
285
286 return new KernelException("UNK000", e.getMessage(), null, e);
287 }
288
289
290
291
292 public KernelException toKernelException() {
293 return this;
294 }
295
296
297
298
299
300
301
302
303 private static String getTextContent(Node node) throws DOMException {
304 StringBuffer sb = new StringBuffer();
305 getTextContent(node, sb);
306 return sb.toString();
307 }
308
309
310
311
312
313
314
315
316
317
318
319 private static void getTextContent(Node node, StringBuffer buf) throws DOMException {
320 if (node.getNodeType() == Node.TEXT_NODE) {
321 buf.append(node.getNodeValue());
322 }
323
324 Node child = node.getFirstChild();
325 while (child != null) {
326 if (child.getNodeType() == Node.TEXT_NODE) {
327 buf.append(child.getNodeValue());
328 }
329 child = child.getNextSibling();
330 }
331 }
332
333
334
335
336
337
338
339
340 @Override
341 public void output(SerializationContext context) throws Exception {
342 prepare();
343 super.output(context);
344 }
345
346
347
348
349
350 @SuppressWarnings("unchecked")
351 protected void prepare() {
352 faultDetails = new Vector();
353
354 setFaultString(getMessage());
355
356 Element el;
357
358
359 el = XMLUtils.StringToElement(Constants.NS_URI_AXIS, "KernelException", "true");
360 faultDetails.add(el);
361
362
363 int count = (params == null) ? 0 : params.length;
364 for (int i = 0; i < count; i++) {
365 el = XMLUtils.StringToElement(Constants.NS_URI_AXIS, "parameter",
366 params[i] == null ? "null" : params[i].toString());
367 faultDetails.add(el);
368 }
369
370
371 el = XMLUtils.StringToElement(Constants.NS_URI_AXIS, "pattern", getPattern());
372 faultDetails.add(el);
373
374 Throwable cause = getCause();
375 if (cause != null) {
376
377
378
379 el = XMLUtils.StringToElement(Constants.NS_URI_AXIS, "exceptionName",
380 cause.getClass().getName());
381
382 faultDetails.add(el);
383
384 el = XMLUtils.StringToElement(Constants.NS_URI_AXIS, "stackTrace",
385 JavaUtils.stackToString(cause));
386
387 faultDetails.add(el);
388 }
389 }
390
391
392
393
394
395
396 @Override public void printStackTrace(PrintWriter out) {
397 synchronized (out) {
398 out.println(this.getCode() + ": " + this.getMessage());
399
400 Throwable cause = this.getCause();
401 if (cause != null) {
402 out.println("Caused By:");
403 out.println(cause.toString());
404 } else {
405 cause = this;
406 }
407 StackTraceElement[] trace = cause.getStackTrace();
408 int count = trace == null ? 0 : trace.length;
409 int max = traceLength(trace);
410 for (int i = 0; i < max; i++) {
411 out.println("\tat " + trace[i]);
412 }
413 if (max < count) {
414 out.println("\tat " + trace[max]);
415 out.println("\t... [" + (count - max - 1) + " elements omitted]");
416 }
417 }
418 }
419
420
421
422
423
424
425 @Override public void printStackTrace(PrintStream out) {
426 synchronized (out) {
427 out.println(this.getCode() + ": " + this.getMessage());
428
429 Throwable cause = this.getCause();
430 if (cause != null) {
431 out.println("Caused By:");
432 out.println(cause.toString());
433 } else {
434 cause = this;
435 }
436 StackTraceElement[] trace = cause.getStackTrace();
437 int count = trace == null ? 0 : trace.length;
438 int max = traceLength(trace);
439 for (int i = 0; i < max; i++) {
440 out.println("\tat " + trace[i]);
441 }
442 if (max < count) {
443 out.println("\tat " + trace[max]);
444 out.println("\t... [" + (count - max - 1) + " elements omitted]");
445 }
446 }
447 }
448
449
450
451
452
453
454
455 private static int traceLength(StackTraceElement[] trace) {
456 int count = trace == null ? 0 : trace.length;
457 boolean skip = false;
458
459 for (int i = 0; i < count; i++) {
460 String s = trace[i].getClassName() + '.' + trace[i].getMethodName();
461
462 boolean match = excludePattern.matcher(s).matches();
463 if (skip && match) {
464 return i;
465 } else if (!skip) {
466 skip = !match;
467 }
468 }
469
470 return count;
471 }
472
473
474
475
476 private static Pattern excludePattern
477 = Pattern.compile("(^(java\\.|javax\\.|sun\\.reflect\\.).+)"
478 + "|^(.+(\\.ApiProvider\\.invokeMethod))");
479
480 }