View Javadoc

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                      String token = st.nextToken();
78                      paths.add((new File(token)).getCanonicalFile().toURL());
79                  }
80                  cl = new WeavingClassLoader((URL[]) paths.toArray(new URL[] {}), ClassLoader.getSystemClassLoader()
81                          .getParent());
82              } catch (IOException e) {
83                  throw new WrappedRuntimeException(e);
84              }
85          }
86  
87          /***
88           * Runs a single test (testXX) Takes care of not using the weaving class loader is online mode or
89           * weavingClassLoader.main() is already used (might fail under JRockit MAPI)
90           * 
91           * @param testClassName test class
92           * @param testMethodName test method
93           * @throws java.lang.Throwable
94           */
95          public void runTest(String testClassName, String testMethodName) throws Throwable {
96              // skip test embedded weaving if online mode / weavingClassLoader.main() is already used
97              if ((cl.getClass().getClassLoader() == null)
98                  || (cl.getClass().getClassLoader().getClass().getName().indexOf("hook.impl.Weaving") > 0)) {
99                  ;
100             } else {
101                 Thread.currentThread().setContextClassLoader(cl); // needed for Aspect loading
102             }
103             Class testClass = Class.forName(testClassName, true, Thread.currentThread().getContextClassLoader());
104 
105             //)cl.loadClass(testClassName);
106             Constructor ctor = null;
107             Object testInstance = null;
108             try {
109                 // new junit style
110                 ctor = testClass.getConstructor(new Class[] {});
111                 testInstance = ctor.newInstance(new Object[] {});
112                 Method setNameMethod = testClass.getMethod("setExpression", new Class[] {
113                     String.class
114                 });
115                 setNameMethod.invoke(testInstance, new Object[] {
116                     testMethodName
117                 });
118             } catch (NoSuchMethodException e) {
119                 ctor = testClass.getConstructor(new Class[] {
120                     String.class
121                 });
122                 testInstance = ctor.newInstance(new Object[] {
123                     testMethodName
124                 });
125             }
126             Method runAfterWeavingMethod = testClass.getMethod("runBareAfterWeaving", new Class[] {});
127             runAfterWeavingMethod.invoke(testInstance, new Object[] {});
128         }
129     }
130 }