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 }