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