1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jelly.tags.junit;
17
18 import org.apache.commons.jelly.JellyException;
19 import org.apache.commons.jelly.JellyTagException;
20 import org.apache.commons.jelly.XMLOutput;
21 import org.apache.commons.jelly.util.ClassLoaderUtils;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 /***
26 * Runs its body and asserts that an exception is thrown by it. If no
27 * exception is thrown the tag fails. By default all exceptions are caught.
28 * If however <code>expected</code> was specified the body must throw
29 * an exception of the given class, otherwise the assertion fails. The
30 * exception thrown by the body can also be of any subtype of the specified
31 * exception class. The optional <code>var</code> attribute can be specified if
32 * the caught exception is to be exported to a variable.
33 */
34 public class AssertThrowsTag extends AssertTagSupport {
35
36 /*** The Log to which logging calls will be made. */
37 private static final Log log = LogFactory.getLog(AssertThrowsTag.class);
38
39 /***
40 * The variable name to export the caught exception to.
41 */
42 private String var;
43
44 /***
45 * The class name (fully qualified) of the exception expected to be thrown
46 * by the body. Also a superclass of the expected exception can be given.
47 */
48 private String expected;
49
50 /***
51 * Sets the ClassLoader to be used when loading an exception class
52 */
53 private ClassLoader classLoader;
54
55
56
57 public void doTag(XMLOutput output) throws JellyTagException {
58 Class throwableClass = null;
59 try {
60 throwableClass = getThrowableClass();
61 } catch (ClassNotFoundException e) {
62 throw new JellyTagException(e);
63 }
64
65 try {
66 invokeBody(output);
67 }
68 catch (Throwable t) {
69 if (t instanceof JellyException) {
70
71 JellyException je = (JellyException) t;
72 if (je.getCause() != null) {
73 t = je.getCause();
74 }
75 }
76 if (var != null) {
77 context.setVariable(var, t);
78 }
79 if (throwableClass != null && !throwableClass.isAssignableFrom(t.getClass())) {
80 fail("Unexpected exception: " + t);
81 }
82 else {
83 return;
84 }
85 }
86 fail("No exception was thrown.");
87 }
88
89
90
91 /***
92 * Sets the class name of exception expected to be thrown by the body. The
93 * class name must be fully qualified and can either be the expected
94 * exception class itself or any supertype of it, but must be a subtype of
95 * <code>java.lang.Throwable</code>.
96 */
97 public void setExpected(String expected) {
98 this.expected = expected;
99 }
100
101 /***
102 * Sets the variable name to define for this expression.
103 */
104 public void setVar(String var) {
105 this.var = var;
106 }
107
108 /***
109 * Sets the class loader to be used to load the exception type
110 */
111 public void setClassLoader(ClassLoader classLoader) {
112 this.classLoader = classLoader;
113 }
114
115 public ClassLoader getClassLoader() {
116 return ClassLoaderUtils.getClassLoader(classLoader, getContext().getUseContextClassLoader(), getClass());
117 }
118
119
120
121
122 /***
123 * Returns the <code>Class</code> corresponding to the class
124 * specified by <code>expected</code>. If
125 * <code>expected</code> was either not specified then <code>java. lang.
126 * Throwable</code> is returned.
127 * Otherwise if the class couldn't be
128 * found or doesn't denote an exception class then an exception is thrown.
129 *
130 * @return Class The class of the exception to expect
131 */
132 protected Class getThrowableClass() throws ClassNotFoundException {
133 if (expected == null) {
134 return Throwable.class;
135 }
136
137 Class throwableClass = null;
138 try {
139 throwableClass = getClassLoader().loadClass(expected);
140 }
141 catch (ClassNotFoundException e) {
142 try {
143 throwableClass = Thread.currentThread().getContextClassLoader().loadClass(expected);
144 }
145 catch (ClassNotFoundException e2) {
146 log.warn( "Could not find exception class: " + expected );
147 throw e;
148 }
149 }
150
151 if (!Throwable.class.isAssignableFrom(throwableClass)) {
152 log.warn( "The class: " + expected + " is not an Exception class.");
153 return null;
154 }
155 return throwableClass;
156 }
157 }