1package org.junit.internal.runners;
2
3import java.lang.annotation.Annotation;
4import java.lang.reflect.InvocationTargetException;
5import java.lang.reflect.Method;
6import java.util.Collections;
7import java.util.Comparator;
8import java.util.Iterator;
9import java.util.List;
10
11import org.junit.runner.Description;
12import org.junit.runner.Runner;
13import org.junit.runner.manipulation.Filter;
14import org.junit.runner.manipulation.Filterable;
15import org.junit.runner.manipulation.NoTestsRemainException;
16import org.junit.runner.manipulation.Sortable;
17import org.junit.runner.manipulation.Sorter;
18import org.junit.runner.notification.Failure;
19import org.junit.runner.notification.RunNotifier;
20import org.junit.runners.BlockJUnit4ClassRunner;
21
22/**
23 * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
24 *             removed in the next release. Please use
25 *             {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
26 *
27 *             This may disappear as soon as 1 April 2009
28 */
29@Deprecated
30public class JUnit4ClassRunner extends Runner implements Filterable, Sortable {
31	private final List<Method> fTestMethods;
32	private TestClass fTestClass;
33
34	public JUnit4ClassRunner(Class<?> klass) throws InitializationError {
35		fTestClass= new TestClass(klass);
36		fTestMethods= getTestMethods();
37		validate();
38	}
39
40	protected List<Method> getTestMethods() {
41		return fTestClass.getTestMethods();
42	}
43
44	protected void validate() throws InitializationError {
45		MethodValidator methodValidator= new MethodValidator(fTestClass);
46		methodValidator.validateMethodsForDefaultRunner();
47		methodValidator.assertValid();
48	}
49
50	@Override
51	public void run(final RunNotifier notifier) {
52		new ClassRoadie(notifier, fTestClass, getDescription(), new Runnable() {
53			public void run() {
54				runMethods(notifier);
55			}
56		}).runProtected();
57	}
58
59	protected void runMethods(final RunNotifier notifier) {
60		for (Method method : fTestMethods)
61			invokeTestMethod(method, notifier);
62	}
63
64	@Override
65	public Description getDescription() {
66		Description spec= Description.createSuiteDescription(getName(), classAnnotations());
67		List<Method> testMethods= fTestMethods;
68		for (Method method : testMethods)
69			spec.addChild(methodDescription(method));
70		return spec;
71	}
72
73	protected Annotation[] classAnnotations() {
74		return fTestClass.getJavaClass().getAnnotations();
75	}
76
77	protected String getName() {
78		return getTestClass().getName();
79	}
80
81	protected Object createTest() throws Exception {
82		return getTestClass().getConstructor().newInstance();
83	}
84
85	protected void invokeTestMethod(Method method, RunNotifier notifier) {
86		Description description= methodDescription(method);
87		Object test;
88		try {
89			test= createTest();
90		} catch (InvocationTargetException e) {
91			testAborted(notifier, description, e.getCause());
92			return;
93		} catch (Exception e) {
94			testAborted(notifier, description, e);
95			return;
96		}
97		TestMethod testMethod= wrapMethod(method);
98		new MethodRoadie(test, testMethod, notifier, description).run();
99	}
100
101	private void testAborted(RunNotifier notifier, Description description,
102			Throwable e) {
103		notifier.fireTestStarted(description);
104		notifier.fireTestFailure(new Failure(description, e));
105		notifier.fireTestFinished(description);
106	}
107
108	protected TestMethod wrapMethod(Method method) {
109		return new TestMethod(method, fTestClass);
110	}
111
112	protected String testName(Method method) {
113		return method.getName();
114	}
115
116	protected Description methodDescription(Method method) {
117		return Description.createTestDescription(getTestClass().getJavaClass(), testName(method), testAnnotations(method));
118	}
119
120	protected Annotation[] testAnnotations(Method method) {
121		return method.getAnnotations();
122	}
123
124	public void filter(Filter filter) throws NoTestsRemainException {
125		for (Iterator<Method> iter= fTestMethods.iterator(); iter.hasNext();) {
126			Method method= iter.next();
127			if (!filter.shouldRun(methodDescription(method)))
128				iter.remove();
129		}
130		if (fTestMethods.isEmpty())
131			throw new NoTestsRemainException();
132	}
133
134	public void sort(final Sorter sorter) {
135		Collections.sort(fTestMethods, new Comparator<Method>() {
136			public int compare(Method o1, Method o2) {
137				return sorter.compare(methodDescription(o1), methodDescription(o2));
138			}
139		});
140	}
141
142	protected TestClass getTestClass() {
143		return fTestClass;
144	}
145}