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 * @since 1.5
31 */
32 public class ExceptionUtils
33 {
34 private static boolean causesAllowed = true;
35
36 /**
37 * Create a new RuntimeException, setting the cause if possible.
38 * @param message
39 * @param cause
40 * @return A runtime exception object.
41 */
42 public static RuntimeException createRuntimeException(
43 String message, Throwable cause)
44 {
45 return (RuntimeException) createWithCause(
46 RuntimeException.class, message, cause);
47 }
48
49 /**
50 * Create a new Exception, setting the cause if possible.
51 * @param clazz
52 * @param message
53 * @param cause
54 * @return A Throwable.
55 */
56 public static Throwable createWithCause(Class clazz,
57 String message, Throwable cause)
58 {
59 Throwable re = null;
60 if (causesAllowed)
61 {
62 try
63 {
64 Constructor constructor = clazz
65 .getConstructor(new Class[]{String.class,
66 Throwable.class});
67 re = (Throwable) constructor
68 .newInstance(new Object[]{message, cause});
69 }
70 catch (RuntimeException e)
71 {
72 throw e;
73 }
74 catch (Exception e)
75 {
76 causesAllowed = false;
77 }
78 }
79 if (re == null)
80 {
81 try
82 {
83 Constructor constructor = clazz
84 .getConstructor(new Class[]{String.class});
85 re = (Throwable) constructor
86 .newInstance(new Object[]{message
87 + " caused by " + cause});
88 }
89 catch (RuntimeException e)
90 {
91 throw e;
92 }
93 catch (Exception e)
94 {
95 throw new RuntimeException("Error caused " + e); // should be impossible
96 }
97 }
98 return re;
99 }
100
101 /**
102 * Set the cause of the Exception. Will detect if this is not allowed.
103 * @param onObject
104 * @param cause
105 */
106 public static void setCause(Throwable onObject, Throwable cause)
107 {
108 if (causesAllowed)
109 {
110 try
111 {
112 Method method = onObject.getClass().getMethod("initCause", new Class[]{Throwable.class});
113 method.invoke(onObject, new Object[]{cause});
114 }
115 catch (RuntimeException e)
116 {
117 throw e;
118 }
119 catch (Exception e)
120 {
121 causesAllowed = false;
122 }
123 }
124 }
125 }