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 org.apache.maven.surefire.util.NestedRuntimeException;
23  import org.apache.maven.surefire.util.ReflectionUtils;
24  
25  import java.lang.reflect.Constructor;
26  import java.lang.reflect.InvocationTargetException;
27  import java.lang.reflect.Method;
28  import java.lang.reflect.Modifier;
29  
30  public final class JUnit3Reflector
31  {
32      private static final String TEST_CASE = "junit.framework.Test";
33  
34      private static final String TEST_RESULT = "junit.framework.TestResult";
35  
36      private static final String TEST_LISTENER = "junit.framework.TestListener";
37  
38      private static final String TEST = "junit.framework.Test";
39  
40      private static final String ADD_LISTENER_METHOD = "addListener";
41  
42      private static final String RUN_METHOD = "run";
43  
44      private static final String TEST_SUITE = "junit.framework.TestSuite";
45  
46      private final Class[] interfacesImplementedByDynamicProxy;
47  
48      private final Class testResultClass;
49  
50      private final Method addListenerMethod;
51  
52      private final Method testInterfaceRunMethod;
53  
54      private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
55  
56      private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
57  
58      private final Class testInterface;
59  
60      private final Class testCase;
61  
62      private final Constructor testsSuiteConstructor;
63  
64      public JUnit3Reflector( ClassLoader testClassLoader )
65      {
66          testResultClass = ReflectionUtils.tryLoadClass( testClassLoader, TEST_RESULT );
67          testCase = ReflectionUtils.tryLoadClass( testClassLoader, TEST_CASE );
68          testInterface = ReflectionUtils.tryLoadClass( testClassLoader, TEST );
69          interfacesImplementedByDynamicProxy =
70              new Class[]{ ReflectionUtils.tryLoadClass( testClassLoader, TEST_LISTENER ) };
71          Class[] constructorParamTypes = { Class.class };
72  
73          Class testSuite = ReflectionUtils.tryLoadClass( testClassLoader, TEST_SUITE );
74  
75          // The interface implemented by the dynamic proxy (TestListener), happens to be
76          // the same as the param types of TestResult.addTestListener
77          Class[] addListenerParamTypes = interfacesImplementedByDynamicProxy;
78  
79          if ( isJUnit3Available() )
80          {
81              testsSuiteConstructor = ReflectionUtils.getConstructor( testSuite, constructorParamTypes );
82              addListenerMethod = tryGetMethod( testResultClass, ADD_LISTENER_METHOD, addListenerParamTypes );
83              testInterfaceRunMethod = getMethod( testInterface, RUN_METHOD, new Class[]{ testResultClass } );
84          }
85          else
86          {
87              testsSuiteConstructor = null;
88              addListenerMethod = null;
89              testInterfaceRunMethod = null;
90          }
91      }
92  
93      // Switch to reflectionutils when building with 2.7.2
94      private static Method tryGetMethod( Class clazz, String methodName, Class[] parameters )
95      {
96          try
97          {
98              return clazz.getMethod( methodName, parameters );
99          }
100         catch ( NoSuchMethodException e )
101         {
102             return null;
103         }
104     }
105 
106     private static Method getMethod( Class clazz, String methodName, Class[] parameters )
107     {
108         try
109         {
110             return clazz.getMethod( methodName, parameters );
111         }
112         catch ( NoSuchMethodException e )
113         {
114             throw new NestedRuntimeException( "When finding method " + methodName, e );
115         }
116     }
117 
118 
119     public Object constructTestObject( Class testClass )
120         throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException,
121         ClassNotFoundException
122     {
123         Object testObject = createInstanceFromSuiteMethod( testClass );
124 
125         if ( testObject == null && testCase.isAssignableFrom( testClass ) )
126         {
127             Object[] constructorParams = { testClass };
128 
129             testObject = testsSuiteConstructor.newInstance( constructorParams );
130         }
131 
132         if ( testObject == null )
133         {
134             Constructor testConstructor = getTestConstructor( testClass );
135 
136             if ( testConstructor.getParameterTypes().length == 0 )
137             {
138                 testObject = testConstructor.newInstance( EMPTY_OBJECT_ARRAY );
139             }
140             else
141             {
142                 testObject = testConstructor.newInstance( new Object[]{ testClass.getName() } );
143             }
144         }
145         return testObject;
146     }
147 
148     private static Object createInstanceFromSuiteMethod( Class testClass )
149         throws IllegalAccessException, InvocationTargetException
150     {
151         Object testObject = null;
152         try
153         {
154             Method suiteMethod = testClass.getMethod( "suite", EMPTY_CLASS_ARRAY );
155 
156             if ( Modifier.isPublic( suiteMethod.getModifiers() ) && Modifier.isStatic( suiteMethod.getModifiers() ) )
157             {
158                 testObject = suiteMethod.invoke( null, EMPTY_CLASS_ARRAY );
159             }
160         }
161         catch ( NoSuchMethodException e )
162         {
163             // No suite method
164         }
165         return testObject;
166     }
167 
168     private static Constructor getTestConstructor( Class testClass )
169         throws NoSuchMethodException
170     {
171         Constructor constructor;
172         try
173         {
174             constructor = testClass.getConstructor( new Class[]{ String.class } );
175         }
176         catch ( NoSuchMethodException e )
177         {
178             constructor = testClass.getConstructor( EMPTY_CLASS_ARRAY );
179         }
180         return constructor;
181     }
182 
183     public Class[] getInterfacesImplementedByDynamicProxy()
184     {
185         return interfacesImplementedByDynamicProxy;
186     }
187 
188     public Class getTestResultClass()
189     {
190         return testResultClass;
191     }
192 
193     public Method getAddListenerMethod()
194     {
195         return addListenerMethod;
196     }
197 
198     public Method getTestInterfaceRunMethod()
199     {
200         return testInterfaceRunMethod;
201     }
202 
203     public Class getTestInterface()
204     {
205         return testInterface;
206     }
207 
208     public Method getRunMethod( Class testClass )
209     {
210         return getMethod( testClass, RUN_METHOD, new Class[]{ getTestResultClass() } );
211     }
212 
213     public boolean isJUnit3Available()
214     {
215         return testResultClass != null;
216     }
217 }