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                  boolean.class,
95                  statelessTestsetReporter,
96                  consoleOutputReporter,
97                  statelessTestsetInfoReporter,
98                  reporterFactoryOptions);
99          Object[] params = {
100             reporterConfiguration.isUseFile(),
101             reporterConfiguration.isPrintSummary(),
102             reporterConfiguration.getReportFormat(),
103             reporterConfiguration.isRedirectTestOutputToFile(),
104             reporterConfiguration.getReportsDirectory(),
105             reporterConfiguration.isTrimStackTrace(),
106             reporterConfiguration.getReportNameSuffix(),
107             reporterConfiguration.getStatisticsFile(),
108             reporterConfiguration.isRequiresRunHistory(),
109             reporterConfiguration.getRerunFailingTestsCount(),
110             reporterConfiguration.getXsdSchemaLocation(),
111             reporterConfiguration.getEncoding().name(),
112             reporterConfiguration.isForking(),
113             reporterConfiguration.isEnableOutErrElements(),
114             reporterConfiguration.isEnablePropertiesElement(),
115             reporterConfiguration.isReportTestTimestamp(),
116             reporterConfiguration.getXmlReporter().clone(surefireClassLoader),
117             reporterConfiguration.getConsoleOutputReporter().clone(surefireClassLoader),
118             reporterConfiguration.getTestsetReporter().clone(surefireClassLoader),
119             reporterConfiguration.getReporterFactoryOptions().clone(surefireClassLoader)
120         };
121         return newInstance(constructor, params);
122     }
123 
124     static Object createConsoleLogger(ConsoleLogger consoleLogger, ClassLoader cl) {
125         try {
126             Class<?> decoratorClass = cl.loadClass(ConsoleLoggerDecorator.class.getName());
127             return getConstructor(decoratorClass, Object.class).newInstance(consoleLogger);
128         } catch (Exception e) {
129             throw new SurefireReflectionException(e);
130         }
131     }
132 }