View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.surefire;
20  
21  import javax.annotation.Nonnull;
22  
23  import java.io.File;
24  import java.lang.reflect.Constructor;
25  
26  import org.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporter;
27  import org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter;
28  import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
29  import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
30  import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerDecorator;
31  import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
32  import org.apache.maven.surefire.api.report.ReporterFactoryOptions;
33  import org.apache.maven.surefire.api.util.SurefireReflectionException;
34  
35  import static org.apache.maven.surefire.api.util.ReflectionUtils.getConstructor;
36  import static org.apache.maven.surefire.api.util.ReflectionUtils.instantiateObject;
37  import static org.apache.maven.surefire.api.util.ReflectionUtils.newInstance;
38  
39  /**
40   * @author Kristian Rosenvold
41   */
42  public class CommonReflector {
43      private final Class<?> startupReportConfiguration;
44      private final Class<?> consoleLogger;
45      private final Class<?> statelessTestsetReporter;
46      private final Class<?> consoleOutputReporter;
47      private final Class<?> statelessTestsetInfoReporter;
48      private final Class<?> reporterFactoryOptions;
49      private final ClassLoader surefireClassLoader;
50  
51      public CommonReflector(@Nonnull ClassLoader surefireClassLoader) {
52          this.surefireClassLoader = surefireClassLoader;
53  
54          try {
55              startupReportConfiguration = surefireClassLoader.loadClass(StartupReportConfiguration.class.getName());
56              consoleLogger = surefireClassLoader.loadClass(ConsoleLogger.class.getName());
57              statelessTestsetReporter = surefireClassLoader.loadClass(SurefireStatelessReporter.class.getName());
58              consoleOutputReporter = surefireClassLoader.loadClass(SurefireConsoleOutputReporter.class.getName());
59              statelessTestsetInfoReporter =
60                      surefireClassLoader.loadClass(SurefireStatelessTestsetInfoReporter.class.getName());
61              reporterFactoryOptions = surefireClassLoader.loadClass(ReporterFactoryOptions.class.getName());
62          } catch (ClassNotFoundException e) {
63              throw new SurefireReflectionException(e);
64          }
65      }
66  
67      public Object createReportingReporterFactory(
68              @Nonnull StartupReportConfiguration startupReportConfiguration, @Nonnull ConsoleLogger consoleLogger) {
69          Class<?>[] args = {this.startupReportConfiguration, this.consoleLogger};
70          Object src = createStartupReportConfiguration(startupReportConfiguration);
71          Object logger = createConsoleLogger(consoleLogger, surefireClassLoader);
72          Object[] params = {src, logger};
73          return instantiateObject(DefaultReporterFactory.class.getName(), args, params, surefireClassLoader);
74      }
75  
76      private Object createStartupReportConfiguration(@Nonnull StartupReportConfiguration reporterConfiguration) {
77          Constructor<?> constructor = getConstructor(
78                  startupReportConfiguration,
79                  boolean.class,
80                  boolean.class,
81                  String.class,
82                  boolean.class,
83                  File.class,
84                  boolean.class,
85                  String.class,
86                  File.class,
87                  boolean.class,
88                  int.class,
89                  String.class,
90                  String.class,
91                  boolean.class,
92                  boolean.class,
93                  boolean.class,
94                  statelessTestsetReporter,
95                  consoleOutputReporter,
96                  statelessTestsetInfoReporter,
97                  reporterFactoryOptions);
98          Object[] params = {
99              reporterConfiguration.isUseFile(),
100             reporterConfiguration.isPrintSummary(),
101             reporterConfiguration.getReportFormat(),
102             reporterConfiguration.isRedirectTestOutputToFile(),
103             reporterConfiguration.getReportsDirectory(),
104             reporterConfiguration.isTrimStackTrace(),
105             reporterConfiguration.getReportNameSuffix(),
106             reporterConfiguration.getStatisticsFile(),
107             reporterConfiguration.isRequiresRunHistory(),
108             reporterConfiguration.getRerunFailingTestsCount(),
109             reporterConfiguration.getXsdSchemaLocation(),
110             reporterConfiguration.getEncoding().name(),
111             reporterConfiguration.isForking(),
112             reporterConfiguration.isEnableOutErrElements(),
113             reporterConfiguration.isEnablePropertiesElement(),
114             reporterConfiguration.getXmlReporter().clone(surefireClassLoader),
115             reporterConfiguration.getConsoleOutputReporter().clone(surefireClassLoader),
116             reporterConfiguration.getTestsetReporter().clone(surefireClassLoader),
117             reporterConfiguration.getReporterFactoryOptions().clone(surefireClassLoader)
118         };
119         return newInstance(constructor, params);
120     }
121 
122     static Object createConsoleLogger(ConsoleLogger consoleLogger, ClassLoader cl) {
123         try {
124             Class<?> decoratorClass = cl.loadClass(ConsoleLoggerDecorator.class.getName());
125             return getConstructor(decoratorClass, Object.class).newInstance(consoleLogger);
126         } catch (Exception e) {
127             throw new SurefireReflectionException(e);
128         }
129     }
130 }