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