| 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.api.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 static final Class[] EMPTY_CLASS_ARRAY = { }; |
| |
| private static final Object[] EMPTY_OBJECT_ARRAY = { }; |
| |
| private final Class[] interfacesImplementedByDynamicProxy; |
| |
| private final Class<?> testResultClass; |
| |
| private final Method addListenerMethod; |
| |
| private final Method testInterfaceRunMethod; |
| |
| 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 |
| |
| if ( isJUnit3Available() ) |
| { |
| testsSuiteConstructor = ReflectionUtils.getConstructor( testSuite, constructorParamTypes ); |
| addListenerMethod = |
| tryGetMethod( testResultClass, ADD_LISTENER_METHOD, interfacesImplementedByDynamicProxy ); |
| 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_OBJECT_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; |
| } |
| } |