View Javadoc
1   /*
2    * Copyright (c) 2006 JMockit developers
3    * This file is subject to the terms of the MIT license (see LICENSE.txt).
4    */
5   package mockit.internal.startup;
6   
7   import static java.util.Arrays.asList;
8   
9   import static mockit.internal.util.ClassLoad.loadClassAtStartup;
10  import static mockit.internal.util.ClassLoad.searchTypeInClasspath;
11  
12  import edu.umd.cs.findbugs.annotations.NonNull;
13  
14  import java.lang.instrument.Instrumentation;
15  import java.util.Collection;
16  import java.util.Collections;
17  import java.util.HashSet;
18  import java.util.Set;
19  
20  import mockit.MockUp;
21  import mockit.coverage.CodeCoverage;
22  import mockit.integration.junit4.FakeFrameworkMethod;
23  import mockit.integration.junit4.FakeRunNotifier;
24  import mockit.internal.reflection.ConstructorReflection;
25  import mockit.internal.util.StackTrace;
26  
27  final class JMockitInitialization {
28      private JMockitInitialization() {
29      }
30  
31      static void initialize(@NonNull Instrumentation inst, boolean activateCoverage) {
32          if (activateCoverage || CodeCoverage.active()) {
33              inst.addTransformer(new CodeCoverage());
34          }
35  
36          applyInternalStartupFakesAsNeeded();
37          applyUserSpecifiedStartupFakesIfAny();
38      }
39  
40      private static void applyInternalStartupFakesAsNeeded() {
41          if (searchTypeInClasspath("org.junit.runners.model.FrameworkMethod", true) != null
42                  || searchTypeInClasspath("org.junit.vintage.engine.VintageTestEngine", true) != null) {
43              new FakeRunNotifier();
44              new FakeFrameworkMethod();
45          }
46  
47          if (searchTypeInClasspath("org.junit.jupiter.api.extension.Extension", true) != null) {
48              System.setProperty("junit.jupiter.extensions.autodetection.enabled", "true");
49          }
50      }
51  
52      private static void applyUserSpecifiedStartupFakesIfAny() {
53          Collection<String> fakeClasses = getFakeClasses();
54  
55          for (String fakeClassName : fakeClasses) {
56              applyStartupFake(fakeClassName);
57          }
58      }
59  
60      @NonNull
61      private static Collection<String> getFakeClasses() {
62          String commaOrSpaceSeparatedValues = System.getProperty("fakes");
63  
64          if (commaOrSpaceSeparatedValues == null) {
65              return Collections.emptyList();
66          }
67  
68          // noinspection DynamicRegexReplaceableByCompiledPattern
69          String[] fakeClassNames = commaOrSpaceSeparatedValues.split("\\s*,\\s*|\\s+");
70          Set<String> uniqueClassNames = new HashSet<>(asList(fakeClassNames));
71          uniqueClassNames.remove("");
72          return uniqueClassNames;
73      }
74  
75      private static void applyStartupFake(@NonNull String fakeClassName) {
76          String argument = null;
77          int p = fakeClassName.indexOf('=');
78  
79          if (p > 0) {
80              argument = fakeClassName.substring(p + 1);
81              fakeClassName = fakeClassName.substring(0, p);
82          }
83  
84          try {
85              Class<?> fakeClass = loadClassAtStartup(fakeClassName);
86  
87              if (MockUp.class.isAssignableFrom(fakeClass)) {
88                  if (argument == null) {
89                      ConstructorReflection.newInstanceUsingDefaultConstructor(fakeClass);
90                  } else {
91                      ConstructorReflection.newInstanceUsingCompatibleConstructor(fakeClass, argument);
92                  }
93              }
94          } catch (UnsupportedOperationException ignored) {
95          } catch (Throwable unexpectedFailure) {
96              StackTrace.filterStackTrace(unexpectedFailure);
97              unexpectedFailure.printStackTrace();
98          }
99      }
100 }