1 package org.apache.velocity.util;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.lang.reflect.Constructor;
23 import java.lang.reflect.Method;
24
25 /**
26 * Use this to create a new Exception. This will run under JDK 1.3 or greater.
27 * However, it running under JDK 1.4 it will set the cause.
28 *
29 * @author <a href="mailto:isidore@setgame.com">Llewellyn Falco</a>
30 */
31 public class ExceptionUtils
32 {
33 private static boolean causesAllowed = true;
34
35 /**
36 * Create a new RuntimeException, setting the cause if possible.
37 * @param message
38 * @param cause
39 * @return A runtime exception object.
40 */
41 public static RuntimeException createRuntimeException(
42 String message, Throwable cause)
43 {
44 return (RuntimeException) createWithCause(
45 RuntimeException.class, message, cause);
46 }
47
48 /**
49 * Create a new Exception, setting the cause if possible.
50 * @param clazz
51 * @param message
52 * @param cause
53 * @return A Throwable.
54 */
55 public static Throwable createWithCause(Class clazz,
56 String message, Throwable cause)
57 {
58 Throwable re = null;
59 if (causesAllowed)
60 {
61 try
62 {
63 Constructor constructor = clazz
64 .getConstructor(new Class[]{String.class,
65 Throwable.class});
66 re = (Throwable) constructor
67 .newInstance(new Object[]{message, cause});
68 }
69 catch (RuntimeException e)
70 {
71 throw e;
72 }
73 catch (Exception e)
74 {
75 causesAllowed = false;
76 }
77 }
78 if (re == null)
79 {
80 try
81 {
82 Constructor constructor = clazz
83 .getConstructor(new Class[]{String.class});
84 re = (Throwable) constructor
85 .newInstance(new Object[]{message
86 + " caused by " + cause});
87 }
88 catch (RuntimeException e)
89 {
90 throw e;
91 }
92 catch (Exception e)
93 {
94 throw new RuntimeException("Error caused " + e); // should be impossible
95 }
96 }
97 return re;
98 }
99
100 /**
101 * Set the cause of the Exception. Will detect if this is not allowed.
102 * @param onObject
103 * @param cause
104 */
105 public static void setCause(Throwable onObject, Throwable cause)
106 {
107 if (causesAllowed)
108 {
109 try
110 {
111 Method method = onObject.getClass().getMethod("initCause", new Class[]{Throwable.class});
112 method.invoke(onObject, new Object[]{cause});
113 }
114 catch (RuntimeException e)
115 {
116 throw e;
117 }
118 catch (Exception e)
119 {
120 causesAllowed = false;
121 }
122 }
123 }
124 }