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                      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              // skip test embedded weaving if online mode / weavingClassLoader.main() is already used
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); // needed for Aspect loading
103             }
104             Class testClass = Class.forName(testClassName, true, Thread.currentThread().getContextClassLoader());
105 
106             //)cl.loadClass(testClassName);
107             Constructor ctor = null;
108             Object testInstance = null;
109             try {
110                 // new junit style
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 }