View Javadoc

1   package org.apache.maven.surefire.common.junit3;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.Constructor;
23  import java.lang.reflect.InvocationTargetException;
24  import java.lang.reflect.Method;
25  import java.lang.reflect.Modifier;
26  import org.apache.maven.surefire.util.NestedRuntimeException;
27  import org.apache.maven.surefire.util.ReflectionUtils;
28  
29  public final class JUnit3Reflector
30  {
31      private static final String TEST_CASE = "junit.framework.Test";
32  
33      private static final String TEST_RESULT = "junit.framework.TestResult";
34  
35      private static final String TEST_LISTENER = "junit.framework.TestListener";
36  
37      private static final String TEST = "junit.framework.Test";
38  
39      private static final String ADD_LISTENER_METHOD = "addListener";
40  
41      private static final String RUN_METHOD = "run";
42  
43      private static final String TEST_SUITE = "junit.framework.TestSuite";
44  
45      private final Class[] interfacesImplementedByDynamicProxy;
46  
47      private final Class testResultClass;
48  
49      private final Method addListenerMethod;
50  
51      private final Method testInterfaceRunMethod;
52  
53      private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
54  
55      private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
56  
57      private final Class testInterface;
58  
59      private final Class testCase;
60  
61      private final Constructor testsSuiteConstructor;
62  
63      public JUnit3Reflector( ClassLoader testClassLoader )
64      {
65          testResultClass = ReflectionUtils.tryLoadClass( testClassLoader, TEST_RESULT );
66          testCase = ReflectionUtils.tryLoadClass( testClassLoader, TEST_CASE );
67          testInterface = ReflectionUtils.tryLoadClass( testClassLoader, TEST );
68          interfacesImplementedByDynamicProxy =
69              new Class[]{ ReflectionUtils.tryLoadClass( testClassLoader, TEST_LISTENER ) };
70          Class[] constructorParamTypes = { Class.class };
71  
72          Class testSuite = ReflectionUtils.tryLoadClass( testClassLoader, TEST_SUITE );
73  
74          // The interface implemented by the dynamic proxy (TestListener), happens to be
75          // the same as the param types of TestResult.addTestListener
76          Class[] addListenerParamTypes = interfacesImplementedByDynamicProxy;
77  
78          if ( isJUnit3Available() )
79          {
80              testsSuiteConstructor = ReflectionUtils.getConstructor( testSuite, constructorParamTypes );
81              addListenerMethod = tryGetMethod( testResultClass, ADD_LISTENER_METHOD, addListenerParamTypes );
82              testInterfaceRunMethod = getMethod( testInterface, RUN_METHOD, new Class[]{ testResultClass } );
83          }
84          else
85          {
86              testsSuiteConstructor = null;
87              addListenerMethod = null;
88              testInterfaceRunMethod = null;
89          }
90      }
91  
92      // Switch to reflectionutils when building with 2.7.2
93      private static Method tryGetMethod( Class clazz, String methodName, Class[] parameters )
94      {
95          try
96          {
97              return clazz.getMethod( methodName, parameters );
98          }
99          catch ( NoSuchMethodException e )
100         {
101             return null;
102         }
103     }
104 
105     private static Method getMethod( Class clazz, String methodName, Class[] parameters )
106     {
107         try
108         {
109             return clazz.getMethod( methodName, parameters );
110         }
111         catch ( NoSuchMethodException e )
112         {
113             throw new NestedRuntimeException( "When finding method " + methodName, e );
114         }
115     }
116 
117 
118     public Object constructTestObject( Class testClass )
119         throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException
120     {
121         Object testObject = createInstanceFromSuiteMethod( testClass );
122 
123         if ( testObject == null && testCase.isAssignableFrom( testClass ) )
124         {
125             Object[] constructorParams = { testClass };
126 
127             testObject = testsSuiteConstructor.newInstance( constructorParams );
128         }
129 
130         if ( testObject == null )
131         {
132             Constructor testConstructor = getTestConstructor( testClass );
133 
134             if ( testConstructor.getParameterTypes().length == 0 )
135             {
136                 testObject = testConstructor.newInstance( EMPTY_OBJECT_ARRAY );
137             }
138             else
139             {
140                 testObject = testConstructor.newInstance( new Object[]{ testClass.getName() } );
141             }
142         }
143         return testObject;
144     }
145 
146     private static Object createInstanceFromSuiteMethod( Class testClass )
147         throws IllegalAccessException, InvocationTargetException
148     {
149         Object testObject = null;
150         try
151         {
152             Method suiteMethod = testClass.getMethod( "suite", EMPTY_CLASS_ARRAY );
153 
154             if ( Modifier.isPublic( suiteMethod.getModifiers() ) && Modifier.isStatic( suiteMethod.getModifiers() ) )
155             {
156                 testObject = suiteMethod.invoke( null, EMPTY_CLASS_ARRAY );
157             }
158         }
159         catch ( NoSuchMethodException e )
160         {
161             // No suite method
162         }
163         return testObject;
164     }
165 
166     private static Constructor getTestConstructor( Class testClass )
167         throws NoSuchMethodException
168     {
169         Constructor constructor;
170         try
171         {
172             constructor = testClass.getConstructor( new Class[]{ String.class } );
173         }
174         catch ( NoSuchMethodException e )
175         {
176             constructor = testClass.getConstructor( EMPTY_CLASS_ARRAY );
177         }
178         return constructor;
179     }
180 
181     public Class[] getInterfacesImplementedByDynamicProxy()
182     {
183         return interfacesImplementedByDynamicProxy;
184     }
185 
186     public Class getTestResultClass()
187     {
188         return testResultClass;
189     }
190 
191     public Method getAddListenerMethod()
192     {
193         return addListenerMethod;
194     }
195 
196     public Method getTestInterfaceRunMethod()
197     {
198         return testInterfaceRunMethod;
199     }
200 
201     public Class getTestInterface()
202     {
203         return testInterface;
204     }
205 
206     public Method getRunMethod( Class testClass )
207     {
208         return getMethod( testClass, RUN_METHOD, new Class[]{ getTestResultClass() } );
209     }
210 
211     public boolean isJUnit3Available()
212     {
213         return testResultClass != null;
214     }
215 }