Coverage Report - org.apache.maven.surefire.booter.SurefireReflector
 
Classes in this File Line Coverage Branch Coverage Complexity
SurefireReflector
0%
0/92
0%
0/28
1,808
SurefireReflector$ClassLoaderProxy
0%
0/5
N/A
1,808
 
 1  
 package org.apache.maven.surefire.booter;
 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.io.File;
 23  
 import java.io.PrintStream;
 24  
 import java.lang.reflect.Constructor;
 25  
 import java.lang.reflect.InvocationHandler;
 26  
 import java.lang.reflect.Method;
 27  
 import java.util.List;
 28  
 import java.util.Properties;
 29  
 import org.apache.maven.surefire.providerapi.ProviderParameters;
 30  
 import org.apache.maven.surefire.report.ReporterConfiguration;
 31  
 import org.apache.maven.surefire.report.ReporterFactory;
 32  
 import org.apache.maven.surefire.suite.RunResult;
 33  
 import org.apache.maven.surefire.testset.DirectoryScannerParameters;
 34  
 import org.apache.maven.surefire.testset.RunOrderParameters;
 35  
 import org.apache.maven.surefire.testset.TestArtifactInfo;
 36  
 import org.apache.maven.surefire.testset.TestRequest;
 37  
 import org.apache.maven.surefire.util.ReflectionUtils;
 38  
 import org.apache.maven.surefire.util.RunOrder;
 39  
 import org.apache.maven.surefire.util.SurefireReflectionException;
 40  
 
 41  
 /**
 42  
  * Does reflection based invocation of the surefire methods.
 43  
  * <p/>
 44  
  * This is to avoid complications with linkage issues
 45  
  *
 46  
  * @author Kristian Rosenvold
 47  
  */
 48  
 public class SurefireReflector
 49  
 {
 50  
     private final ClassLoader surefireClassLoader;
 51  
 
 52  
     private final Class reporterConfiguration;
 53  
 
 54  
     private final Class testRequest;
 55  
 
 56  
     private final Class testArtifactInfo;
 57  
 
 58  
     private final Class testArtifactInfoAware;
 59  
 
 60  
     private final Class directoryScannerParameters;
 61  
 
 62  
     private final Class runOrderParameters;
 63  
 
 64  
     private final Class directoryScannerParametersAware;
 65  
 
 66  
     private final Class testSuiteDefinitionAware;
 67  
 
 68  
     private final Class testClassLoaderAware;
 69  
 
 70  
     private final Class reporterConfigurationAware;
 71  
 
 72  
     private final Class providerPropertiesAware;
 73  
 
 74  
     private final Class runResult;
 75  
 
 76  
     private final Class booterParameters;
 77  
 
 78  
     private final Class reporterFactory;
 79  
 
 80  
 
 81  
     public SurefireReflector( ClassLoader surefireClassLoader )
 82  0
     {
 83  0
         this.surefireClassLoader = surefireClassLoader;
 84  
         try
 85  
         {
 86  0
             reporterConfiguration = surefireClassLoader.loadClass( ReporterConfiguration.class.getName() );
 87  0
             testRequest = surefireClassLoader.loadClass( TestRequest.class.getName() );
 88  0
             testArtifactInfo = surefireClassLoader.loadClass( TestArtifactInfo.class.getName() );
 89  0
             testArtifactInfoAware = surefireClassLoader.loadClass( TestArtifactInfoAware.class.getName() );
 90  0
             directoryScannerParameters = surefireClassLoader.loadClass( DirectoryScannerParameters.class.getName() );
 91  0
             runOrderParameters = surefireClassLoader.loadClass( RunOrderParameters.class.getName() );
 92  0
             directoryScannerParametersAware =
 93  
                 surefireClassLoader.loadClass( DirectoryScannerParametersAware.class.getName() );
 94  0
             testSuiteDefinitionAware = surefireClassLoader.loadClass( TestRequestAware.class.getName() );
 95  0
             testClassLoaderAware = surefireClassLoader.loadClass( SurefireClassLoadersAware.class.getName() );
 96  0
             reporterConfigurationAware = surefireClassLoader.loadClass( ReporterConfigurationAware.class.getName() );
 97  0
             providerPropertiesAware = surefireClassLoader.loadClass( ProviderPropertiesAware.class.getName() );
 98  0
             reporterFactory = surefireClassLoader.loadClass( ReporterFactory.class.getName() );
 99  0
             runResult = surefireClassLoader.loadClass( RunResult.class.getName() );
 100  0
             booterParameters = surefireClassLoader.loadClass( ProviderParameters.class.getName() );
 101  
         }
 102  0
         catch ( ClassNotFoundException e )
 103  
         {
 104  0
             throw new SurefireReflectionException( e );
 105  0
         }
 106  0
     }
 107  
 
 108  
     public Object convertIfRunResult( Object result )
 109  
     {
 110  0
         if ( result == null || !isRunResult( result ) )
 111  
         {
 112  0
             return result;
 113  
         }
 114  0
         final Integer getCompletedCount1 = (Integer) ReflectionUtils.invokeGetter( result, "getCompletedCount" );
 115  0
         final Integer getErrors = (Integer) ReflectionUtils.invokeGetter( result, "getErrors" );
 116  0
         final Integer getSkipped = (Integer) ReflectionUtils.invokeGetter( result, "getSkipped" );
 117  0
         final Integer getFailures = (Integer) ReflectionUtils.invokeGetter( result, "getFailures" );
 118  0
         return new RunResult( getCompletedCount1, getErrors, getFailures, getSkipped );
 119  
 
 120  
     }
 121  
 
 122  
 
 123  
     /**
 124  
      * @noinspection UnusedDeclaration
 125  
      */
 126  
     class ClassLoaderProxy
 127  
         implements InvocationHandler
 128  
     {
 129  
         private final Object target;
 130  
 
 131  
         /**
 132  
          * @param delegate a target
 133  
          * @noinspection UnusedDeclaration
 134  
          */
 135  
         public ClassLoaderProxy( Object delegate )
 136  0
         {
 137  0
             this.target = delegate;
 138  0
         }
 139  
 
 140  
         public Object invoke( Object proxy, Method method, Object[] args )
 141  
             throws Throwable
 142  
         {
 143  0
             Method delegateMethod = target.getClass().getMethod( method.getName(), method.getParameterTypes() );
 144  0
             return delegateMethod.invoke( target, args );
 145  
         }
 146  
     }
 147  
 
 148  
 
 149  
     Object createTestRequest( TestRequest suiteDefinition )
 150  
     {
 151  0
         if ( suiteDefinition == null )
 152  
         {
 153  0
             return null;
 154  
         }
 155  0
         Class[] arguments = { List.class, File.class, String.class, String.class };
 156  0
         Constructor constructor = ReflectionUtils.getConstructor( this.testRequest, arguments );
 157  0
         return ReflectionUtils.newInstance( constructor, new Object[]{ suiteDefinition.getSuiteXmlFiles(),
 158  
             suiteDefinition.getTestSourceDirectory(), suiteDefinition.getRequestedTest(),
 159  
             suiteDefinition.getRequestedTestMethod() } );
 160  
     }
 161  
 
 162  
 
 163  
     Object createDirectoryScannerParameters( DirectoryScannerParameters directoryScannerParameters )
 164  
     {
 165  0
         if ( directoryScannerParameters == null )
 166  
         {
 167  0
             return null;
 168  
         }
 169  
         //Can't use the constructor with the RunOrder parameter. Using it causes some integration tests to fail.
 170  0
         Class[] arguments = { File.class, List.class, List.class, List.class, Boolean.class, String.class };
 171  0
         Constructor constructor = ReflectionUtils.getConstructor( this.directoryScannerParameters, arguments );
 172  0
         return ReflectionUtils.newInstance( constructor,
 173  
                                             new Object[]{ directoryScannerParameters.getTestClassesDirectory(),
 174  
                                                 directoryScannerParameters.getIncludes(),
 175  
                                                 directoryScannerParameters.getExcludes(),
 176  
                                                 directoryScannerParameters.getSpecificTests(),
 177  
                                                 directoryScannerParameters.isFailIfNoTests(),
 178  
                                                 RunOrder.asString( directoryScannerParameters.getRunOrder() ) } );
 179  
     }
 180  
 
 181  
 
 182  
     Object createRunOrderParameters( RunOrderParameters runOrderParameters )
 183  
     {
 184  0
         if ( runOrderParameters == null )
 185  
         {
 186  0
             return null;
 187  
         }
 188  
         //Can't use the constructor with the RunOrder parameter. Using it causes some integration tests to fail.
 189  0
         Class[] arguments = { String.class, String.class };
 190  0
         Constructor constructor = ReflectionUtils.getConstructor( this.runOrderParameters, arguments );
 191  0
         final File runStatisticsFile = runOrderParameters.getRunStatisticsFile();
 192  0
         return ReflectionUtils.newInstance( constructor,
 193  
                                             new Object[]{ RunOrder.asString( runOrderParameters.getRunOrder() ),
 194  
                                                 runStatisticsFile != null
 195  
                                                     ? runStatisticsFile.getAbsolutePath()
 196  
                                                     : null } );
 197  
     }
 198  
 
 199  
     Object createTestArtifactInfo( TestArtifactInfo testArtifactInfo )
 200  
     {
 201  0
         if ( testArtifactInfo == null )
 202  
         {
 203  0
             return null;
 204  
         }
 205  0
         Class[] arguments = { String.class, String.class };
 206  0
         Constructor constructor = ReflectionUtils.getConstructor( this.testArtifactInfo, arguments );
 207  0
         return ReflectionUtils.newInstance( constructor, new Object[]{ testArtifactInfo.getVersion(),
 208  
             testArtifactInfo.getClassifier() } );
 209  
     }
 210  
 
 211  
 
 212  
     Object createReporterConfiguration( ReporterConfiguration reporterConfiguration )
 213  
     {
 214  0
         Constructor constructor =
 215  
             ReflectionUtils.getConstructor( this.reporterConfiguration, new Class[]{ File.class, Boolean.class } );
 216  0
         return ReflectionUtils.newInstance( constructor, new Object[]{ reporterConfiguration.getReportsDirectory(),
 217  
             reporterConfiguration.isTrimStackTrace() } );
 218  
     }
 219  
 
 220  
     public static ReporterFactory createForkingReporterFactoryInCurrentClassLoader( Boolean trimStackTrace, PrintStream originalSystemOut )
 221  
     {
 222  0
         return new ForkingReporterFactory( trimStackTrace, originalSystemOut );
 223  
     }
 224  
 
 225  
     public Object createBooterConfiguration( ClassLoader surefireClassLoader, Object factoryInstance,
 226  
                                              boolean insideFork )
 227  
     {
 228  0
         return ReflectionUtils.instantiateTwoArgs( surefireClassLoader, BaseProviderFactory.class.getName(),
 229  
                                                    reporterFactory, factoryInstance, Boolean.class,
 230  
                                                    insideFork ? Boolean.TRUE : Boolean.FALSE );
 231  
     }
 232  
 
 233  
     public Object instantiateProvider( String providerClassName, Object booterParameters )
 234  
     {
 235  0
         return ReflectionUtils.instantiateOneArg( surefireClassLoader, providerClassName, this.booterParameters,
 236  
                                                   booterParameters );
 237  
     }
 238  
 
 239  
     public void setIfDirScannerAware( Object o, DirectoryScannerParameters dirScannerParams )
 240  
     {
 241  0
         if ( directoryScannerParametersAware.isAssignableFrom( o.getClass() ) )
 242  
         {
 243  0
             setDirectoryScannerParameters( o, dirScannerParams );
 244  
         }
 245  0
     }
 246  
 
 247  
     public void setDirectoryScannerParameters( Object o, DirectoryScannerParameters dirScannerParams )
 248  
     {
 249  0
         final Object param = createDirectoryScannerParameters( dirScannerParams );
 250  0
         ReflectionUtils.invokeSetter( o, "setDirectoryScannerParameters", this.directoryScannerParameters, param );
 251  0
     }
 252  
 
 253  
     public void setRunOrderParameters( Object o, RunOrderParameters runOrderParameters )
 254  
     {
 255  0
         final Object param = createRunOrderParameters( runOrderParameters );
 256  0
         ReflectionUtils.invokeSetter( o, "setRunOrderParameters", this.runOrderParameters, param );
 257  0
     }
 258  
 
 259  
 
 260  
     public void setTestSuiteDefinitionAware( Object o, TestRequest testSuiteDefinition2 )
 261  
     {
 262  0
         if ( testSuiteDefinitionAware.isAssignableFrom( o.getClass() ) )
 263  
         {
 264  0
             setTestSuiteDefinition( o, testSuiteDefinition2 );
 265  
         }
 266  0
     }
 267  
 
 268  
     void setTestSuiteDefinition( Object o, TestRequest testSuiteDefinition1 )
 269  
     {
 270  0
         final Object param = createTestRequest( testSuiteDefinition1 );
 271  0
         ReflectionUtils.invokeSetter( o, "setTestRequest", this.testRequest, param );
 272  0
     }
 273  
 
 274  
     public void setProviderPropertiesAware( Object o, Properties properties )
 275  
     {
 276  0
         if ( providerPropertiesAware.isAssignableFrom( o.getClass() ) )
 277  
         {
 278  0
             setProviderProperties( o, properties );
 279  
         }
 280  0
     }
 281  
 
 282  
     void setProviderProperties( Object o, Properties providerProperties )
 283  
     {
 284  0
         ReflectionUtils.invokeSetter( o, "setProviderProperties", Properties.class, providerProperties );
 285  0
     }
 286  
 
 287  
     public void setReporterConfigurationAware( Object o, ReporterConfiguration reporterConfiguration1 )
 288  
     {
 289  0
         if ( reporterConfigurationAware.isAssignableFrom( o.getClass() ) )
 290  
         {
 291  0
             setReporterConfiguration( o, reporterConfiguration1 );
 292  
         }
 293  0
     }
 294  
 
 295  
 
 296  
     void setReporterConfiguration( Object o, ReporterConfiguration reporterConfiguration )
 297  
     {
 298  0
         final Object param = createReporterConfiguration( reporterConfiguration );
 299  0
         ReflectionUtils.invokeSetter( o, "setReporterConfiguration", this.reporterConfiguration, param );
 300  0
     }
 301  
 
 302  
     public void setTestClassLoaderAware( Object o, ClassLoader testClassLoader )
 303  
     {
 304  0
         if ( testClassLoaderAware.isAssignableFrom( o.getClass() ) )
 305  
         {
 306  0
             setTestClassLoader( o, testClassLoader );
 307  
         }
 308  0
     }
 309  
 
 310  
     void setTestClassLoader( Object o, ClassLoader testClassLoader )
 311  
     {
 312  0
         final Method setter =
 313  
             ReflectionUtils.getMethod( o, "setClassLoaders", new Class[]{ ClassLoader.class } );
 314  0
         ReflectionUtils.invokeMethodWithArray( o, setter, new Object[]{ testClassLoader } );
 315  0
     }
 316  
 
 317  
     public void setTestArtifactInfoAware( Object o, TestArtifactInfo testArtifactInfo1 )
 318  
     {
 319  0
         if ( testArtifactInfoAware.isAssignableFrom( o.getClass() ) )
 320  
         {
 321  0
             setTestArtifactInfo( o, testArtifactInfo1 );
 322  
         }
 323  0
     }
 324  
 
 325  
     void setTestArtifactInfo( Object o, TestArtifactInfo testArtifactInfo )
 326  
     {
 327  0
         final Object param = createTestArtifactInfo( testArtifactInfo );
 328  0
         ReflectionUtils.invokeSetter( o, "setTestArtifactInfo", this.testArtifactInfo, param );
 329  0
     }
 330  
 
 331  
     private boolean isRunResult( Object o )
 332  
     {
 333  0
         return runResult.isAssignableFrom( o.getClass() );
 334  
     }
 335  
 
 336  
 }