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(
82 (URL[]) paths.toArray(new URL[]{}), ClassLoader
83 .getSystemClassLoader().getParent()
84 );
85 } catch (IOException e) {
86 throw new WrappedRuntimeException(e);
87 }
88 }
89
90 /***
91 * Runs a single test (testXX) Takes care of not using the weaving class loader is online
92 * mode or weavingClassLoader.main() is already used (might fail under JRockit MAPI)
93 *
94 * @param testClassName test class
95 * @param testMethodName test method
96 * @throws Throwable
97 */
98 public void runTest(String testClassName, String testMethodName) throws Throwable {
99
100 if ((cl.getClass().getClassLoader() == null)
101 || (cl.getClass().getClassLoader().getClass().getName()
102 .indexOf("hook.impl.Weaving") > 0)) {
103 ;
104 } else {
105 Thread.currentThread().setContextClassLoader(cl);
106 }
107 Class testClass = Class.forName(
108 testClassName, true, Thread.currentThread()
109 .getContextClassLoader()
110 );
111
112
113 Constructor ctor = null;
114 Object testInstance = null;
115 try {
116
117 ctor = testClass.getConstructor(new Class[]{});
118 testInstance = ctor.newInstance(new Object[]{});
119 Method setNameMethod = testClass.getMethod(
120 "setExpression", new Class[]{
121 String.class
122 }
123 );
124 setNameMethod.invoke(
125 testInstance, new Object[]{
126 testMethodName
127 }
128 );
129 } catch (NoSuchMethodException e) {
130 ctor = testClass.getConstructor(
131 new Class[]{
132 String.class
133 }
134 );
135 testInstance = ctor.newInstance(
136 new Object[]{
137 testMethodName
138 }
139 );
140 }
141 Method runAfterWeavingMethod = testClass.getMethod(
142 "runBareAfterWeaving",
143 new Class[]{}
144 );
145 runAfterWeavingMethod.invoke(testInstance, new Object[]{});
146 }
147 }
148 }