/**************************************************************************************
* Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved. *
* http://aspectwerkz.codehaus.org *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the LGPL license *
* a copy of which has been included with this distribution in the license.txt file. *
**************************************************************************************/
package org.codehaus.aspectwerkz;
import junit.framework.TestCase;
import org.codehaus.aspectwerkz.hook.impl.WeavingClassLoader;
import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.System;
/**
* Transparently runs TestCase with an embedded online mode Write a JUnit test case and extends WeaverTestCase.
*
* @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a>
*/
public class WeavedTestCase extends TestCase {
/**
* the test runner that runs the test thru reflection in a weaving ClassLoader
*/
private static WeaverTestRunner s_runner = new WeaverTestRunner();
public WeavedTestCase() {
super();
}
public WeavedTestCase(String name) {
super(name);
}
/**
* Overrides JUnit runBare() to run thru the weaverTestRunner This allow WeaverTestCase to be regular TestCase
*
* @throws java.lang.Throwable
*/
public void runBare() throws Throwable {
s_runner.runTest(this.getClass().getName(), getName());
}
/**
* Callback the regulare JUnit runBare()
*
* @throws java.lang.Throwable
*/
public void runBareAfterWeaving() throws Throwable {
super.runBare();
}
/**
* Allow to run WeaverTestCase thru a weaving ClassLoader
*/
public static class WeaverTestRunner {
/**
* Weaving classloader
*/
private WeavingClassLoader cl;
/**
* Build weavin classloader with system class path and ext. classloader as parent
*/
public WeaverTestRunner() {
try {
String path = System.getProperty("java.class.path");
ArrayList paths = new ArrayList();
StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
while (st.hasMoreTokens()) {
paths.add((new File(st.nextToken())).getCanonicalFile().toURL());
}
cl =
new WeavingClassLoader(
(URL[])paths.toArray(new URL[]{}), ClassLoader.getSystemClassLoader().getParent()
);
}
catch (IOException e) {
throw new WrappedRuntimeException(e);
}
}
/**
* Runs a single test (testXX) Takes care of not using the weaving class loader is online mode or
* weavingClassLoader.main() is already used (might fail under JRockit MAPI)
*
* @param testClassName test class
* @param testMethodName test method
* @throws java.lang.Throwable
*/
public void runTest(String testClassName, String testMethodName) throws Throwable {
// skip test embedded weaving if online mode / weavingClassLoader.main() is already used
if (cl.getClass().getClassLoader() == null ||
cl.getClass().getClassLoader().getClass().getName().indexOf("hook.impl.Weaving") > 0) {
;
}
else {
Thread.currentThread().setContextClassLoader(cl);// needed for Aspect loading
}
Class testClass = Class.forName(testClassName, true, Thread.currentThread().getContextClassLoader());
//)cl.loadClass(testClassName);
Constructor ctor = null;
Object testInstance = null;
try {
// new junit style
ctor = testClass.getConstructor(new Class[]{});
testInstance = ctor.newInstance(new Object[]{});
Method setNameMethod = testClass.getMethod("setName", new Class[]{String.class});
setNameMethod.invoke(testInstance, new Object[]{testMethodName});
}
catch (NoSuchMethodException e) {
ctor = testClass.getConstructor(new Class[]{String.class});
testInstance = ctor.newInstance(new Object[]{testMethodName});
}
Method runAfterWeavingMethod = testClass.getMethod("runBareAfterWeaving", new Class[]{});
runAfterWeavingMethod.invoke(testInstance, new Object[]{});
}
}
}