1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.github.springtestdbunit;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import org.springframework.test.context.TestContext;
26 import org.springframework.test.context.TestExecutionListener;
27
28
29
30
31
32
33
34
35
36
37
38
39 public abstract class TestExecutionListenerChain implements TestExecutionListener {
40
41 private List<TestExecutionListener> chain;
42
43 private List<TestExecutionListener> reverseChain;
44
45 public TestExecutionListenerChain() {
46 this.chain = createChain();
47 this.reverseChain = new ArrayList<TestExecutionListener>(this.chain);
48 Collections.reverse(this.reverseChain);
49 }
50
51
52
53
54
55 protected abstract Class<?>[] getChain();
56
57
58
59
60
61
62 protected List<TestExecutionListener> createChain() {
63 Class<?>[] chainClasses = getChain();
64 try {
65 List<TestExecutionListener> chain = new ArrayList<TestExecutionListener>(chainClasses.length);
66 for (int i = 0; i < chainClasses.length; i++) {
67 chain.add((TestExecutionListener) chainClasses[i].newInstance());
68 }
69 return chain;
70 } catch (Exception ex) {
71 throw new IllegalStateException("Unable to create chain for classes " + Arrays.asList(chainClasses), ex);
72 }
73 }
74
75 public void beforeTestClass(final TestContext testContext) throws Exception {
76 forwards(new Call() {
77 public void call(TestExecutionListener listener) throws Exception {
78 listener.beforeTestClass(testContext);
79 }
80 });
81 }
82
83 public void prepareTestInstance(final TestContext testContext) throws Exception {
84 forwards(new Call() {
85 public void call(TestExecutionListener listener) throws Exception {
86 listener.prepareTestInstance(testContext);
87 }
88 });
89 }
90
91 public void beforeTestMethod(final TestContext testContext) throws Exception {
92 forwards(new Call() {
93 public void call(TestExecutionListener listener) throws Exception {
94 listener.beforeTestMethod(testContext);
95 }
96 });
97 }
98
99 public void afterTestMethod(final TestContext testContext) throws Exception {
100 backwards(new Call() {
101 public void call(TestExecutionListener listener) throws Exception {
102 listener.afterTestMethod(testContext);
103 }
104 });
105 }
106
107 public void afterTestClass(final TestContext testContext) throws Exception {
108 backwards(new Call() {
109 public void call(TestExecutionListener listener) throws Exception {
110 listener.afterTestClass(testContext);
111 }
112 });
113 }
114
115 private void forwards(Call call) throws Exception {
116 runChain(this.chain.iterator(), call);
117 }
118
119 private void backwards(Call call) throws Exception {
120 runChain(this.reverseChain.iterator(), call);
121 }
122
123 private void runChain(Iterator<TestExecutionListener> iterator, Call call) throws Exception {
124 Throwable lastException = null;
125 while (iterator.hasNext()) {
126 try {
127 call.call(iterator.next());
128 } catch (Throwable ex) {
129 lastException = ex;
130 }
131 }
132 if (lastException != null) {
133 if (lastException instanceof Exception) {
134 throw (Exception) lastException;
135 }
136 throw new Exception(lastException);
137 }
138 }
139
140 private static interface Call {
141 public void call(TestExecutionListener listener) throws Exception;
142 }
143
144 }