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