1
2
3
4
5 package mockit.coverage.reporting.sourceFiles;
6
7 import edu.umd.cs.findbugs.annotations.NonNull;
8 import edu.umd.cs.findbugs.annotations.Nullable;
9
10 import java.io.BufferedReader;
11 import java.io.File;
12 import java.io.FileFilter;
13 import java.io.IOException;
14 import java.nio.charset.StandardCharsets;
15 import java.nio.file.Files;
16 import java.nio.file.Path;
17 import java.util.List;
18
19 import org.checkerframework.checker.index.qual.NonNegative;
20
21 public final class InputFile {
22 @NonNull
23 final String filePath;
24 @NonNull
25 private final File sourceFile;
26 @NonNull
27 private final BufferedReader input;
28
29 @Nullable
30 public static InputFile createIfFileExists(@NonNull List<File> sourceDirs, @NonNull String filePath)
31 throws IOException {
32 File sourceFile = findSourceFile(sourceDirs, filePath);
33 return sourceFile == null ? null : new InputFile(filePath, sourceFile);
34 }
35
36 @Nullable
37 private static File findSourceFile(@NonNull List<File> sourceDirs, @NonNull String filePath) {
38 int p = filePath.indexOf('/');
39 String topLevelPackage = p < 0 ? "" : filePath.substring(0, p);
40 int n = sourceDirs.size();
41
42 for (int i = 0; i < n; i++) {
43 File sourceDir = sourceDirs.get(i);
44 File sourceFile = getSourceFile(sourceDir, topLevelPackage, filePath);
45
46 if (sourceFile != null) {
47 giveCurrentSourceDirHighestPriority(sourceDirs, i);
48 addRootSourceDirIfNew(sourceDirs, filePath, sourceFile);
49 return sourceFile;
50 }
51 }
52
53 return null;
54 }
55
56 @Nullable
57 private static File getSourceFile(@NonNull File sourceDir, @NonNull final String topLevelPackage,
58 @NonNull String filePath) {
59 File file = sourceDir.toPath().resolve(filePath).toFile();
60
61 if (file.exists()) {
62 return file;
63 }
64
65 File[] subDirs = sourceDir.listFiles((FileFilter) subDir -> subDir.isDirectory() && !subDir.isHidden()
66 && !subDir.getName().equals(topLevelPackage));
67
68 if (subDirs != null && subDirs.length > 0) {
69 for (File subDir : subDirs) {
70 File sourceFile = getSourceFile(subDir, topLevelPackage, filePath);
71
72 if (sourceFile != null) {
73 return sourceFile;
74 }
75 }
76 }
77
78 return null;
79 }
80
81 private static void giveCurrentSourceDirHighestPriority(@NonNull List<File> sourceDirs,
82 @NonNegative int currentSourceDirIndex) {
83 if (currentSourceDirIndex > 0) {
84 File firstSourceDir = sourceDirs.get(0);
85 File currentSourceDir = sourceDirs.get(currentSourceDirIndex);
86
87 if (!firstSourceDir.getPath().startsWith(currentSourceDir.getPath())) {
88 sourceDirs.set(currentSourceDirIndex, firstSourceDir);
89 sourceDirs.set(0, currentSourceDir);
90 }
91 }
92 }
93
94 private static void addRootSourceDirIfNew(@NonNull List<File> sourceDirs, @NonNull String filePath,
95 @NonNull File sourceFile) {
96 String sourceFilePath = sourceFile.getPath();
97 String sourceRootDir = sourceFilePath.substring(0, sourceFilePath.length() - filePath.length());
98 File newSourceDir = Path.of(sourceRootDir).toFile();
99
100 if (!sourceDirs.contains(newSourceDir)) {
101 sourceDirs.add(0, newSourceDir);
102 }
103 }
104
105 private InputFile(@NonNull String filePath, @NonNull File sourceFile) throws IOException {
106 this.filePath = filePath;
107 this.sourceFile = sourceFile;
108 input = Files.newBufferedReader(sourceFile.toPath(), StandardCharsets.UTF_8);
109 }
110
111 @NonNull
112 String getSourceFileName() {
113 return sourceFile.getName();
114 }
115
116 @NonNull
117 String getSourceFilePath() {
118 String path = sourceFile.getPath();
119 return path.startsWith("..") ? path.substring(3) : path;
120 }
121
122 @Nullable
123 String nextLine() throws IOException {
124 return input.readLine();
125 }
126
127 void close() throws IOException {
128 input.close();
129 }
130 }