1
2
3
4
5
6 package mockit.coverage.modification;
7
8 import edu.umd.cs.findbugs.annotations.NonNull;
9
10 import java.io.File;
11 import java.net.URI;
12 import java.net.URISyntaxException;
13 import java.nio.file.Path;
14 import java.security.ProtectionDomain;
15 import java.util.HashSet;
16 import java.util.Set;
17
18 import org.checkerframework.checker.index.qual.NonNegative;
19
20
21
22
23 public final class ClassesNotLoaded {
24 @NonNull
25 private final ClassModification classModification;
26 @NonNegative
27 private int firstPosAfterParentDir;
28
29 public ClassesNotLoaded(@NonNull ClassModification classModification) {
30 this.classModification = classModification;
31 }
32
33 public void gatherCoverageData() {
34 Set<ProtectionDomain> protectionDomainsSoFar = new HashSet<>(
35 classModification.protectionDomainsWithUniqueLocations);
36
37 for (ProtectionDomain pd : protectionDomainsSoFar) {
38 URI location;
39 try {
40 location = pd.getCodeSource().getLocation().toURI();
41 File classPathEntry = Path.of(location).toFile();
42
43 if (!classPathEntry.getPath().endsWith(".jar")) {
44 firstPosAfterParentDir = classPathEntry.getPath().length() + 1;
45 loadAdditionalClasses(classPathEntry, pd);
46 }
47 } catch (URISyntaxException e) {
48
49 }
50 }
51 }
52
53 private void loadAdditionalClasses(@NonNull File classPathEntry, @NonNull ProtectionDomain protectionDomain) {
54 File[] filesInDir = classPathEntry.listFiles();
55
56 if (filesInDir != null) {
57 for (File fileInDir : filesInDir) {
58 if (fileInDir.isDirectory()) {
59 loadAdditionalClasses(fileInDir, protectionDomain);
60 } else {
61 loadAdditionalClass(fileInDir.getPath(), protectionDomain);
62 }
63 }
64 }
65 }
66
67 private void loadAdditionalClass(@NonNull String filePath, @NonNull ProtectionDomain protectionDomain) {
68 int p = filePath.lastIndexOf(".class");
69
70 if (p > 0) {
71 String relativePath = filePath.substring(firstPosAfterParentDir, p);
72 String className = relativePath.replace(File.separatorChar, '.');
73
74 if (classModification.isToBeConsideredForCoverage(className, protectionDomain)) {
75 loadClass(className, protectionDomain);
76 }
77 }
78 }
79
80 private static void loadClass(@NonNull String className, @NonNull ProtectionDomain protectionDomain) {
81 try {
82 Class.forName(className, false, protectionDomain.getClassLoader());
83 } catch (ClassNotFoundException | NoClassDefFoundError ignore) {
84 }
85 }
86 }