Coverage Report - org.apache.maven.surefire.booter.SurefireReflector
 
Classes in this File Line Coverage Branch Coverage Complexity
SurefireReflector
0%
0/94
0%
0/104
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.intValue(), getErrors.intValue(), getFailures.intValue(),
 119  
                               getSkipped.intValue() );
 120  
 
 121  
     }
 122  
 
 123  
 
 124  
     /**
 125  
      * @noinspection UnusedDeclaration
 126  
      */
 127  
     class ClassLoaderProxy
 128  
         implements InvocationHandler
 129  
     {
 130  
         private final Object target;
 131  
 
 132  
         /**
 133  
          * @param delegate a target
 134  
          * @noinspection UnusedDeclaration
 135  
          */
 136  
         public ClassLoaderProxy( Object delegate )
 137  0
         {
 138  0
             this.target = delegate;
 139  0
         }
 140  
 
 141  
         public Object invoke( Object proxy, Method method, Object[] args )
 142  
             throws Throwable
 143  
         {
 144  0
             Method delegateMethod = target.getClass().getMethod( method.getName(), method.getParameterTypes() );
 145  0
             return delegateMethod.invoke( target, args );
 146  
         }
 147  
     }
 148  
 
 149  
 
 150  
     Object createTestRequest( TestRequest suiteDefinition )
 151  
     {
 152  0
         if ( suiteDefinition == null )
 153  
         {
 154  0
             return null;
 155  
         }
 156  0
         Class[] arguments = { List.class, File.class, String.class, String.class };
 157  0
         Constructor constructor = ReflectionUtils.getConstructor( this.testRequest, arguments );
 158  0
         return ReflectionUtils.newInstance( constructor, new Object[]{ suiteDefinition.getSuiteXmlFiles(),
 159  
             suiteDefinition.getTestSourceDirectory(), suiteDefinition.getRequestedTest(),
 160  
             suiteDefinition.getRequestedTestMethod() } );
 161  
     }
 162  
 
 163  
 
 164  
     Object createDirectoryScannerParameters( DirectoryScannerParameters directoryScannerParameters )
 165  
     {
 166  0
         if ( directoryScannerParameters == null )
 167  
         {
 168  0
             return null;
 169  
         }
 170  
         //Can't use the constructor with the RunOrder parameter. Using it causes some integration tests to fail.
 171  0
         Class[] arguments = { File.class, List.class, List.class, List.class, Boolean.class, String.class };
 172  0
         Constructor constructor = ReflectionUtils.getConstructor( this.directoryScannerParameters, arguments );
 173  0
         return ReflectionUtils.newInstance( constructor,
 174  
                                             new Object[]{ directoryScannerParameters.getTestClassesDirectory(),
 175  
                                                 directoryScannerParameters.getIncludes(),
 176  
                                                 directoryScannerParameters.getExcludes(),
 177  
                                                 directoryScannerParameters.getSpecificTests(),
 178  
                                                 directoryScannerParameters.isFailIfNoTests(),
 179  
                                                 RunOrder.asString( directoryScannerParameters.getRunOrder() ) } );
 180  
     }
 181  
 
 182  
 
 183  
     Object createRunOrderParameters( RunOrderParameters runOrderParameters )
 184  
     {
 185  0
         if ( runOrderParameters == null )
 186  
         {
 187  0
             return null;
 188  
         }
 189  
         //Can't use the constructor with the RunOrder parameter. Using it causes some integration tests to fail.
 190  0
         Class[] arguments = { String.class, String.class };
 191  0
         Constructor constructor = ReflectionUtils.getConstructor( this.runOrderParameters, arguments );
 192  0
         final File runStatisticsFile = runOrderParameters.getRunStatisticsFile();
 193  0
         return ReflectionUtils.newInstance( constructor,
 194  
                                             new Object[]{ RunOrder.asString( runOrderParameters.getRunOrder() ),
 195  
                                                 runStatisticsFile != null
 196  
                                                     ? runStatisticsFile.getAbsolutePath()
 197  
                                                     : null } );
 198  
     }
 199  
 
 200  
     Object createTestArtifactInfo( TestArtifactInfo testArtifactInfo )
 201  
     {
 202  0
         if ( testArtifactInfo == null )
 203  
         {
 204  0
             return null;
 205  
         }
 206  0
         Class[] arguments = { String.class, String.class };
 207  0
         Constructor constructor = ReflectionUtils.getConstructor( this.testArtifactInfo, arguments );
 208  0
         return ReflectionUtils.newInstance( constructor, new Object[]{ testArtifactInfo.getVersion(),
 209  
             testArtifactInfo.getClassifier() } );
 210  
     }
 211  
 
 212  
 
 213  
     Object createReporterConfiguration( ReporterConfiguration reporterConfiguration )
 214  
     {
 215  0
         Constructor constructor =
 216  
             ReflectionUtils.getConstructor( this.reporterConfiguration, new Class[]{ File.class, Boolean.class } );
 217  0
         return ReflectionUtils.newInstance( constructor, new Object[]{ reporterConfiguration.getReportsDirectory(),
 218  
             reporterConfiguration.isTrimStackTrace() } );
 219  
     }
 220  
 
 221  
     public Object createForkingReporterFactory( Boolean trimStackTrace, PrintStream originalSystemOut )
 222  
     {
 223  0
         Class[] args = new Class[]{ Boolean.class, PrintStream.class };
 224  0
         Object[] values = new Object[]{ trimStackTrace, originalSystemOut };
 225  0
         return ReflectionUtils.instantiateObject( ForkingReporterFactory.class.getName(), args, values,
 226  
                                                   surefireClassLoader );
 227  
     }
 228  
 
 229  
     public Object createBooterConfiguration( ClassLoader surefireClassLoader, Object factoryInstance,
 230  
                                              boolean insideFork )
 231  
     {
 232  0
         return ReflectionUtils.instantiateTwoArgs( surefireClassLoader, BaseProviderFactory.class.getName(),
 233  
                                                    reporterFactory, factoryInstance, Boolean.class,
 234  
                                                    insideFork ? Boolean.TRUE : Boolean.FALSE );
 235  
     }
 236  
 
 237  
     public Object instantiateProvider( String providerClassName, Object booterParameters )
 238  
     {
 239  0
         return ReflectionUtils.instantiateOneArg( surefireClassLoader, providerClassName, this.booterParameters,
 240  
                                                   booterParameters );
 241  
     }
 242  
 
 243  
     public void setIfDirScannerAware( Object o, DirectoryScannerParameters dirScannerParams )
 244  
     {
 245  0
         if ( directoryScannerParametersAware.isAssignableFrom( o.getClass() ) )
 246  
         {
 247  0
             setDirectoryScannerParameters( o, dirScannerParams );
 248  
         }
 249  0
     }
 250  
 
 251  
     public void setDirectoryScannerParameters( Object o, DirectoryScannerParameters dirScannerParams )
 252  
     {
 253  0
         final Object param = createDirectoryScannerParameters( dirScannerParams );
 254  0
         ReflectionUtils.invokeSetter( o, "setDirectoryScannerParameters", this.directoryScannerParameters, param );
 255  0
     }
 256  
 
 257  
     public void setRunOrderParameters( Object o, RunOrderParameters runOrderParameters )
 258  
     {
 259  0
         final Object param = createRunOrderParameters( runOrderParameters );
 260  0
         ReflectionUtils.invokeSetter( o, "setRunOrderParameters", this.runOrderParameters, param );
 261  0
     }
 262  
 
 263  
 
 264  
     public void setTestSuiteDefinitionAware( Object o, TestRequest testSuiteDefinition2 )
 265  
     {
 266  0
         if ( testSuiteDefinitionAware.isAssignableFrom( o.getClass() ) )
 267  
         {
 268  0
             setTestSuiteDefinition( o, testSuiteDefinition2 );
 269  
         }
 270  0
     }
 271  
 
 272  
     void setTestSuiteDefinition( Object o, TestRequest testSuiteDefinition1 )
 273  
     {
 274  0
         final Object param = createTestRequest( testSuiteDefinition1 );
 275  0
         ReflectionUtils.invokeSetter( o, "setTestRequest", this.testRequest, param );
 276  0
     }
 277  
 
 278  
     public void setProviderPropertiesAware( Object o, Properties properties )
 279  
     {
 280  0
         if ( providerPropertiesAware.isAssignableFrom( o.getClass() ) )
 281  
         {
 282  0
             setProviderProperties( o, properties );
 283  
         }
 284  0
     }
 285  
 
 286  
     void setProviderProperties( Object o, Properties providerProperties )
 287  
     {
 288  0
         ReflectionUtils.invokeSetter( o, "setProviderProperties", Properties.class, providerProperties );
 289  0
     }
 290  
 
 291  
     public void setReporterConfigurationAware( Object o, ReporterConfiguration reporterConfiguration1 )
 292  
     {
 293  0
         if ( reporterConfigurationAware.isAssignableFrom( o.getClass() ) )
 294  
         {
 295  0
             setReporterConfiguration( o, reporterConfiguration1 );
 296  
         }
 297  0
     }
 298  
 
 299  
 
 300  
     void setReporterConfiguration( Object o, ReporterConfiguration reporterConfiguration )
 301  
     {
 302  0
         final Object param = createReporterConfiguration( reporterConfiguration );
 303  0
         ReflectionUtils.invokeSetter( o, "setReporterConfiguration", this.reporterConfiguration, param );
 304  0
     }
 305  
 
 306  
     public void setTestClassLoaderAware( Object o, ClassLoader surefireClassLoader, ClassLoader testClassLoader )
 307  
     {
 308  0
         if ( testClassLoaderAware.isAssignableFrom( o.getClass() ) )
 309  
         {
 310  0
             setTestClassLoader( o, surefireClassLoader, testClassLoader );
 311  
         }
 312  0
     }
 313  
 
 314  
     void setTestClassLoader( Object o, ClassLoader surefireClassLoader, ClassLoader testClassLoader )
 315  
     {
 316  0
         final Method setter =
 317  
             ReflectionUtils.getMethod( o, "setClassLoaders", new Class[]{ ClassLoader.class, ClassLoader.class } );
 318  0
         ReflectionUtils.invokeMethodWithArray( o, setter, new Object[]{ surefireClassLoader, testClassLoader } );
 319  0
     }
 320  
 
 321  
     public void setTestArtifactInfoAware( Object o, TestArtifactInfo testArtifactInfo1 )
 322  
     {
 323  0
         if ( testArtifactInfoAware.isAssignableFrom( o.getClass() ) )
 324  
         {
 325  0
             setTestArtifactInfo( o, testArtifactInfo1 );
 326  
         }
 327  0
     }
 328  
 
 329  
     void setTestArtifactInfo( Object o, TestArtifactInfo testArtifactInfo )
 330  
     {
 331  0
         final Object param = createTestArtifactInfo( testArtifactInfo );
 332  0
         ReflectionUtils.invokeSetter( o, "setTestArtifactInfo", this.testArtifactInfo, param );
 333  0
     }
 334  
 
 335  
     private boolean isRunResult( Object o )
 336  
     {
 337  0
         return runResult.isAssignableFrom( o.getClass() );
 338  
     }
 339  
 
 340  
 }