1 /***************************************************************************************
2 * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. *
3 * http://aspectwerkz.codehaus.org *
4 * ---------------------------------------------------------------------------------- *
5 * The software in this package is published under the terms of the LGPL license *
6 * a copy of which has been included with this distribution in the license.txt file. *
7 **************************************************************************************/
8 package test;
9
10 import junit.framework.TestCase;
11 import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
12 import org.codehaus.aspectwerkz.hook.impl.WeavingClassLoader;
13
14 import java.io.File;
15 import java.io.IOException;
16 import java.lang.reflect.Constructor;
17 import java.lang.reflect.Method;
18 import java.net.URL;
19 import java.util.ArrayList;
20 import java.util.StringTokenizer;
21
22 /***
23 * Transparently runs TestCase with an embedded online mode Write a JUnit test case and extends
24 * WeaverTestCase.
25 *
26 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
27 */
28 public class WeavedTestCase extends TestCase {
29 /***
30 * the test runner that runs the test thru reflection in a weaving ClassLoader
31 */
32 private static WeaverTestRunner s_runner = new WeaverTestRunner();
33
34 public WeavedTestCase() {
35 super();
36 }
37
38 public WeavedTestCase(String name) {
39 super(name);
40 }
41
42 /***
43 * Overrides JUnit runBare() to run thru the weaverTestRunner This allow WeaverTestCase to be
44 * regular TestCase
45 *
46 * @throws Throwable
47 */
48 public void runBare() throws Throwable {
49 s_runner.runTest(this.getClass().getName(), getName());
50 }
51
52 /***
53 * Callback the regulare JUnit runBare()
54 *
55 * @throws Throwable
56 */
57 public void runBareAfterWeaving() throws Throwable {
58 super.runBare();
59 }
60
61 /***
62 * Allow to run WeaverTestCase thru a weaving ClassLoader
63 */
64 public static class WeaverTestRunner {
65 /***
66 * Weaving classloader
67 */
68 private WeavingClassLoader cl;
69
70 /***
71 * Build weavin classloader with system class path and ext. classloader as parent
72 */
73 public WeaverTestRunner() {
74 try {
75 String path = System.getProperty("java.class.path");
76 ArrayList paths = new ArrayList();
77 StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
78 while (st.hasMoreTokens()) {
79 paths.add((new File(st.nextToken())).getCanonicalFile().toURL());
80 }
81 cl = new WeavingClassLoader((URL[]) paths.toArray(new URL[] {}), ClassLoader
82 .getSystemClassLoader().getParent());
83 } catch (IOException e) {
84 throw new WrappedRuntimeException(e);
85 }
86 }
87
88 /***
89 * Runs a single test (testXX) Takes care of not using the weaving class loader is online
90 * mode or weavingClassLoader.main() is already used (might fail under JRockit MAPI)
91 *
92 * @param testClassName test class
93 * @param testMethodName test method
94 * @throws Throwable
95 */
96 public void runTest(String testClassName, String testMethodName) throws Throwable {
97
98 if ((cl.getClass().getClassLoader() == null)
99 || (cl.getClass().getClassLoader().getClass().getName()
100 .indexOf("hook.impl.Weaving") > 0)) {
101 ;
102 } else {
103 Thread.currentThread().setContextClassLoader(cl);
104 }
105 Class testClass = Class.forName(testClassName, true, Thread.currentThread()
106 .getContextClassLoader());
107
108
109 Constructor ctor = null;
110 Object testInstance = null;
111 try {
112
113 ctor = testClass.getConstructor(new Class[] {});
114 testInstance = ctor.newInstance(new Object[] {});
115 Method setNameMethod = testClass.getMethod("setExpression", new Class[] {
116 String.class
117 });
118 setNameMethod.invoke(testInstance, new Object[] {
119 testMethodName
120 });
121 } catch (NoSuchMethodException e) {
122 ctor = testClass.getConstructor(new Class[] {
123 String.class
124 });
125 testInstance = ctor.newInstance(new Object[] {
126 testMethodName
127 });
128 }
129 Method runAfterWeavingMethod = testClass.getMethod(
130 "runBareAfterWeaving",
131 new Class[] {});
132 runAfterWeavingMethod.invoke(testInstance, new Object[] {});
133 }
134 }
135 }