1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.compiler;
20
21 import java.io.IOException;
22 import java.nio.file.Files;
23 import java.nio.file.Path;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.stream.Collectors;
28 import java.util.stream.Stream;
29
30 import org.apache.maven.api.plugin.MojoException;
31
32
33
34
35 public class IncrementalBuildHelper {
36
37
38
39 private static final String MAVEN_STATUS_ROOT = "maven-status";
40
41 public static final String CREATED_FILES_LST_FILENAME = "createdFiles.lst";
42 private static final String INPUT_FILES_LST_FILENAME = "inputFiles.lst";
43
44
45
46
47 private final String mojoStatusPath;
48
49 private final Set<Path> sources;
50
51 private final Path directory;
52
53 private final Path outputDirectory;
54
55
56
57
58
59 private List<Path> filesBeforeAction = Collections.emptyList();
60
61 public IncrementalBuildHelper(String mojoStatusPath, Set<Path> sources, Path directory, Path outputDirectory) {
62 if (mojoStatusPath == null) {
63 throw new IllegalArgumentException("MojoExecution must not be null!");
64 }
65
66 this.mojoStatusPath = mojoStatusPath;
67 this.sources = sources;
68 this.directory = directory;
69 this.outputDirectory = outputDirectory;
70 }
71
72
73
74
75
76
77 public Path getMojoStatusDirectory() throws MojoException {
78
79
80
81 Path mojoStatusDir = directory.resolve(mojoStatusPath);
82
83 try {
84 Files.createDirectories(mojoStatusDir);
85 } catch (IOException e) {
86 throw new MojoException("Unable to create directory: " + mojoStatusDir, e);
87 }
88
89 return mojoStatusDir;
90 }
91
92
93
94
95
96
97
98
99 public boolean inputFileTreeChanged(List<String> added, List<String> removed) {
100 Path mojoConfigBase = getMojoStatusDirectory();
101 Path mojoConfigFile = mojoConfigBase.resolve(INPUT_FILES_LST_FILENAME);
102
103 List<String> oldInputFiles = Collections.emptyList();
104
105 if (Files.exists(mojoConfigFile)) {
106 try {
107 oldInputFiles = Files.readAllLines(mojoConfigFile);
108 } catch (IOException e) {
109 throw new MojoException("Error reading old mojo status " + mojoConfigFile, e);
110 }
111 }
112
113 List<String> newFiles =
114 sources.stream().map(Path::toAbsolutePath).map(Path::toString).collect(Collectors.toList());
115
116 List<String> previousFiles = oldInputFiles;
117 newFiles.stream().filter(s -> !previousFiles.contains(s)).forEach(added::add);
118 previousFiles.stream().filter(s -> !newFiles.contains(s)).forEach(removed::add);
119 try {
120 Files.write(mojoConfigFile, added);
121 } catch (IOException e) {
122 throw new MojoException("Error while storing the mojo status", e);
123 }
124
125 return added.size() + removed.size() > 0;
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 public void beforeRebuildExecution() {
148 Path mojoConfigBase = getMojoStatusDirectory();
149 Path mojoConfigFile = mojoConfigBase.resolve(CREATED_FILES_LST_FILENAME);
150
151 try {
152 if (Files.exists(mojoConfigFile)) {
153 for (String oldFileName : Files.readAllLines(mojoConfigFile)) {
154 Path oldFile = outputDirectory.resolve(oldFileName);
155 Files.deleteIfExists(oldFile);
156 }
157 }
158
159
160 if (Files.exists(outputDirectory)) {
161 try (Stream<Path> walk = Files.walk(outputDirectory)) {
162 filesBeforeAction = walk.filter(Files::isRegularFile).collect(Collectors.toList());
163 }
164 }
165 } catch (IOException e) {
166 throw new MojoException("Error reading old mojo status", e);
167 }
168 }
169
170
171
172
173
174
175
176 public void afterRebuildExecution() {
177 Path mojoConfigBase = getMojoStatusDirectory();
178 Path mojoConfigFile = mojoConfigBase.resolve(CREATED_FILES_LST_FILENAME);
179
180 try {
181 try (Stream<Path> walk = Files.walk(outputDirectory)) {
182 List<String> added = walk.filter(Files::isRegularFile)
183 .filter(p -> !filesBeforeAction.contains(p))
184 .map(Path::toString)
185 .collect(Collectors.toList());
186
187 Files.write(mojoConfigFile, added);
188 }
189 } catch (IOException e) {
190 throw new MojoException("Error while storing the mojo status", e);
191 }
192
193
194
195 mojoConfigFile = mojoConfigBase.resolve(INPUT_FILES_LST_FILENAME);
196 if (!Files.exists(mojoConfigFile)) {
197 try {
198 Files.write(mojoConfigFile, sources.stream().map(Path::toString).collect(Collectors.toList()));
199 } catch (IOException e) {
200 throw new MojoException("Error while storing the mojo status", e);
201 }
202 }
203 }
204 }