package org.apache.maven.surefire.common.junit3; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.apache.maven.surefire.util.ReflectionUtils; /** * Reflection facade for JUnit3 classes * */ public final class JUnit3Reflector { private static final String TEST_CASE = "junit.framework.Test"; private static final String TEST_RESULT = "junit.framework.TestResult"; private static final String TEST_LISTENER = "junit.framework.TestListener"; private static final String TEST = "junit.framework.Test"; private static final String ADD_LISTENER_METHOD = "addListener"; private static final String RUN_METHOD = "run"; private static final String TEST_SUITE = "junit.framework.TestSuite"; private final Class[] interfacesImplementedByDynamicProxy; private final Class<?> testResultClass; private final Method addListenerMethod; private final Method testInterfaceRunMethod; private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; private final Class<?> testInterface; private final Class<?> testCase; private final Constructor testsSuiteConstructor; public JUnit3Reflector( ClassLoader testClassLoader ) { testResultClass = ReflectionUtils.tryLoadClass( testClassLoader, TEST_RESULT ); testCase = ReflectionUtils.tryLoadClass( testClassLoader, TEST_CASE ); testInterface = ReflectionUtils.tryLoadClass( testClassLoader, TEST ); interfacesImplementedByDynamicProxy = new Class[]{ ReflectionUtils.tryLoadClass( testClassLoader, TEST_LISTENER ) }; Class<?>[] constructorParamTypes = { Class.class }; Class<?> testSuite = ReflectionUtils.tryLoadClass( testClassLoader, TEST_SUITE ); // The interface implemented by the dynamic proxy (TestListener), happens to be // the same as the param types of TestResult.addTestListener Class[] addListenerParamTypes = interfacesImplementedByDynamicProxy; if ( isJUnit3Available() ) { testsSuiteConstructor = ReflectionUtils.getConstructor( testSuite, constructorParamTypes ); addListenerMethod = tryGetMethod( testResultClass, ADD_LISTENER_METHOD, addListenerParamTypes ); testInterfaceRunMethod = getMethod( testInterface, RUN_METHOD, testResultClass ); } else { testsSuiteConstructor = null; addListenerMethod = null; testInterfaceRunMethod = null; } } // Switch to reflectionutils when building with 2.7.2 private static Method tryGetMethod( Class<?> clazz, String methodName, Class<?>... parameters ) { try { return clazz.getMethod( methodName, parameters ); } catch ( NoSuchMethodException e ) { return null; } } private static Method getMethod( Class<?> clazz, String methodName, Class<?>... parameters ) { try { return clazz.getMethod( methodName, parameters ); } catch ( NoSuchMethodException e ) { throw new RuntimeException( "When finding method " + methodName, e ); } } public Object constructTestObject( Class testClass ) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException { Object testObject = createInstanceFromSuiteMethod( testClass ); if ( testObject == null && testCase.isAssignableFrom( testClass ) ) { testObject = testsSuiteConstructor.newInstance( testClass ); } if ( testObject == null ) { Constructor testConstructor = getTestConstructor( testClass ); if ( testConstructor.getParameterTypes().length == 0 ) { testObject = testConstructor.newInstance( EMPTY_OBJECT_ARRAY ); } else { testObject = testConstructor.newInstance( testClass.getName() ); } } return testObject; } private static Object createInstanceFromSuiteMethod( Class<?> testClass ) throws IllegalAccessException, InvocationTargetException { Object testObject = null; try { Method suiteMethod = testClass.getMethod( "suite", EMPTY_CLASS_ARRAY ); if ( Modifier.isPublic( suiteMethod.getModifiers() ) && Modifier.isStatic( suiteMethod.getModifiers() ) ) { testObject = suiteMethod.invoke( null, EMPTY_CLASS_ARRAY ); } } catch ( NoSuchMethodException e ) { // No suite method } return testObject; } private static Constructor getTestConstructor( Class<?> testClass ) throws NoSuchMethodException { try { return testClass.getConstructor( String.class ); } catch ( NoSuchMethodException e ) { return testClass.getConstructor( EMPTY_CLASS_ARRAY ); } } public Class[] getInterfacesImplementedByDynamicProxy() { return interfacesImplementedByDynamicProxy; } public Class<?> getTestResultClass() { return testResultClass; } public Method getAddListenerMethod() { return addListenerMethod; } public Method getTestInterfaceRunMethod() { return testInterfaceRunMethod; } public Class<?> getTestInterface() { return testInterface; } public Method getRunMethod( Class<?> testClass ) { return getMethod( testClass, RUN_METHOD, getTestResultClass() ); } public boolean isJUnit3Available() { return testResultClass != null; } }