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 org.codehaus.aspectwerkz;
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 WeaverTestCase.
24 *
25 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
26 */
27 public class WeavedTestCase extends TestCase {
28 /***
29 * the test runner that runs the test thru reflection in a weaving ClassLoader
30 */
31 private static WeaverTestRunner s_runner = new WeaverTestRunner();
32
33 public WeavedTestCase() {
34 super();
35 }
36
37 public WeavedTestCase(String name) {
38 super(name);
39 }
40
41 /***
42 * Overrides JUnit runBare() to run thru the weaverTestRunner This allow WeaverTestCase to be regular TestCase
43 *
44 * @throws java.lang.Throwable
45 */
46 public void runBare() throws Throwable {
47 s_runner.runTest(this.getClass().getName(), getName());
48 }
49
50 /***
51 * Callback the regulare JUnit runBare()
52 *
53 * @throws java.lang.Throwable
54 */
55 public void runBareAfterWeaving() throws Throwable {
56 super.runBare();
57 }
58
59 /***
60 * Allow to run WeaverTestCase thru a weaving ClassLoader
61 */
62 public static class WeaverTestRunner {
63 /***
64 * Weaving classloader
65 */
66 private WeavingClassLoader cl;
67
68 /***
69 * Build weavin classloader with system class path and ext. classloader as parent
70 */
71 public WeaverTestRunner() {
72 try {
73 String path = System.getProperty("java.class.path");
74 ArrayList paths = new ArrayList();
75 StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
76 while (st.hasMoreTokens()) {
77 paths.add((new File(st.nextToken())).getCanonicalFile().toURL());
78 }
79 cl = new WeavingClassLoader(
80 (URL[]) paths.toArray(new URL[]{}), ClassLoader.getSystemClassLoader()
81 .getParent()
82 );
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 mode or
90 * weavingClassLoader.main() is already used (might fail under JRockit MAPI)
91 *
92 * @param testClassName test class
93 * @param testMethodName test method
94 * @throws java.lang.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().indexOf("hook.impl.Weaving") > 0)) {
100 ;
101 } else {
102 Thread.currentThread().setContextClassLoader(cl);
103 }
104 Class testClass = Class.forName(testClassName, true, Thread.currentThread().getContextClassLoader());
105
106
107 Constructor ctor = null;
108 Object testInstance = null;
109 try {
110
111 ctor = testClass.getConstructor(new Class[]{});
112 testInstance = ctor.newInstance(new Object[]{});
113 Method setNameMethod = testClass.getMethod(
114 "setExpression", new Class[]{
115 String.class
116 }
117 );
118 setNameMethod.invoke(
119 testInstance, new Object[]{
120 testMethodName
121 }
122 );
123 } catch (NoSuchMethodException e) {
124 ctor = testClass.getConstructor(
125 new Class[]{
126 String.class
127 }
128 );
129 testInstance = ctor.newInstance(
130 new Object[]{
131 testMethodName
132 }
133 );
134 }
135 Method runAfterWeavingMethod = testClass.getMethod("runBareAfterWeaving", new Class[]{});
136 runAfterWeavingMethod.invoke(testInstance, new Object[]{});
137 }
138 }
139 }