1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.api.cli;
20
21 import java.io.IOException;
22 import java.io.OutputStream;
23 import java.nio.file.Path;
24 import java.nio.file.Paths;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Optional;
30
31 import org.apache.maven.api.annotations.Experimental;
32 import org.apache.maven.api.annotations.Immutable;
33 import org.apache.maven.api.annotations.Nonnull;
34 import org.apache.maven.api.annotations.Nullable;
35
36 import static java.util.Objects.requireNonNull;
37
38
39
40
41
42
43
44
45
46 @Immutable
47 @Experimental
48 public interface ExecutorRequest {
49
50
51
52 String MVN = "mvn";
53
54
55
56
57 @Nonnull
58 String command();
59
60
61
62
63 @Nonnull
64 List<String> arguments();
65
66
67
68
69
70
71
72 @Nonnull
73 Path cwd();
74
75
76
77
78
79
80
81 @Nonnull
82 Path installationDirectory();
83
84
85
86
87
88
89
90 @Nonnull
91 Path userHomeDirectory();
92
93
94
95
96
97
98 @Nonnull
99 Optional<Map<String, String>> jvmSystemProperties();
100
101
102
103
104
105
106
107 @Nonnull
108 Optional<Map<String, String>> environmentVariables();
109
110
111
112
113
114
115
116
117 @Nonnull
118 Optional<List<String>> jvmArguments();
119
120
121
122
123
124
125
126
127 Optional<OutputStream> stdoutConsumer();
128
129
130
131
132
133
134
135
136 Optional<OutputStream> stderrConsumer();
137
138
139
140
141 @Nonnull
142 default Builder toBuilder() {
143 return new Builder(
144 command(),
145 arguments(),
146 cwd(),
147 installationDirectory(),
148 userHomeDirectory(),
149 jvmSystemProperties().orElse(null),
150 environmentVariables().orElse(null),
151 jvmArguments().orElse(null),
152 stdoutConsumer().orElse(null),
153 stderrConsumer().orElse(null));
154 }
155
156
157
158
159
160 @Nonnull
161 static Builder mavenBuilder(@Nullable Path installationDirectory) {
162 return new Builder(
163 MVN,
164 null,
165 getCanonicalPath(Paths.get(System.getProperty("user.dir"))),
166 installationDirectory != null ? getCanonicalPath(installationDirectory) : discoverMavenHome(),
167 getCanonicalPath(Paths.get(System.getProperty("user.home"))),
168 null,
169 null,
170 null,
171 null,
172 null);
173 }
174
175 class Builder {
176 private String command;
177 private List<String> arguments;
178 private Path cwd;
179 private Path installationDirectory;
180 private Path userHomeDirectory;
181 private Map<String, String> jvmSystemProperties;
182 private Map<String, String> environmentVariables;
183 private List<String> jvmArguments;
184 private OutputStream stdoutConsumer;
185 private OutputStream stderrConsumer;
186
187 private Builder() {}
188
189 @SuppressWarnings("ParameterNumber")
190 private Builder(
191 String command,
192 List<String> arguments,
193 Path cwd,
194 Path installationDirectory,
195 Path userHomeDirectory,
196 Map<String, String> jvmSystemProperties,
197 Map<String, String> environmentVariables,
198 List<String> jvmArguments,
199 OutputStream stdoutConsumer,
200 OutputStream stderrConsumer) {
201 this.command = command;
202 this.arguments = arguments;
203 this.cwd = cwd;
204 this.installationDirectory = installationDirectory;
205 this.userHomeDirectory = userHomeDirectory;
206 this.jvmSystemProperties = jvmSystemProperties;
207 this.environmentVariables = environmentVariables;
208 this.jvmArguments = jvmArguments;
209 this.stdoutConsumer = stdoutConsumer;
210 this.stderrConsumer = stderrConsumer;
211 }
212
213 @Nonnull
214 public Builder command(String command) {
215 this.command = requireNonNull(command, "command");
216 return this;
217 }
218
219 @Nonnull
220 public Builder arguments(List<String> arguments) {
221 this.arguments = requireNonNull(arguments, "arguments");
222 return this;
223 }
224
225 @Nonnull
226 public Builder argument(String argument) {
227 if (arguments == null) {
228 arguments = new ArrayList<>();
229 }
230 this.arguments.add(requireNonNull(argument, "argument"));
231 return this;
232 }
233
234 @Nonnull
235 public Builder cwd(Path cwd) {
236 this.cwd = getCanonicalPath(requireNonNull(cwd, "cwd"));
237 return this;
238 }
239
240 @Nonnull
241 public Builder installationDirectory(Path installationDirectory) {
242 this.installationDirectory =
243 getCanonicalPath(requireNonNull(installationDirectory, "installationDirectory"));
244 return this;
245 }
246
247 @Nonnull
248 public Builder userHomeDirectory(Path userHomeDirectory) {
249 this.userHomeDirectory = getCanonicalPath(requireNonNull(userHomeDirectory, "userHomeDirectory"));
250 return this;
251 }
252
253 @Nonnull
254 public Builder jvmSystemProperties(Map<String, String> jvmSystemProperties) {
255 this.jvmSystemProperties = jvmSystemProperties;
256 return this;
257 }
258
259 @Nonnull
260 public Builder jvmSystemProperty(String key, String value) {
261 requireNonNull(key, "env key");
262 requireNonNull(value, "env value");
263 if (jvmSystemProperties == null) {
264 this.jvmSystemProperties = new HashMap<>();
265 }
266 this.jvmSystemProperties.put(key, value);
267 return this;
268 }
269
270 @Nonnull
271 public Builder environmentVariables(Map<String, String> environmentVariables) {
272 this.environmentVariables = environmentVariables;
273 return this;
274 }
275
276 @Nonnull
277 public Builder environmentVariable(String key, String value) {
278 requireNonNull(key, "env key");
279 requireNonNull(value, "env value");
280 if (environmentVariables == null) {
281 this.environmentVariables = new HashMap<>();
282 }
283 this.environmentVariables.put(key, value);
284 return this;
285 }
286
287 @Nonnull
288 public Builder jvmArguments(List<String> jvmArguments) {
289 this.jvmArguments = jvmArguments;
290 return this;
291 }
292
293 @Nonnull
294 public Builder jvmArgument(String jvmArgument) {
295 if (jvmArguments == null) {
296 jvmArguments = new ArrayList<>();
297 }
298 this.jvmArguments.add(requireNonNull(jvmArgument, "jvmArgument"));
299 return this;
300 }
301
302 @Nonnull
303 public Builder stdoutConsumer(OutputStream stdoutConsumer) {
304 this.stdoutConsumer = stdoutConsumer;
305 return this;
306 }
307
308 @Nonnull
309 public Builder stderrConsumer(OutputStream stderrConsumer) {
310 this.stderrConsumer = stderrConsumer;
311 return this;
312 }
313
314 @Nonnull
315 public ExecutorRequest build() {
316 return new Impl(
317 command,
318 arguments,
319 cwd,
320 installationDirectory,
321 userHomeDirectory,
322 jvmSystemProperties,
323 environmentVariables,
324 jvmArguments,
325 stdoutConsumer,
326 stderrConsumer);
327 }
328
329 private static class Impl implements ExecutorRequest {
330 private final String command;
331 private final List<String> arguments;
332 private final Path cwd;
333 private final Path installationDirectory;
334 private final Path userHomeDirectory;
335 private final Map<String, String> jvmSystemProperties;
336 private final Map<String, String> environmentVariables;
337 private final List<String> jvmArguments;
338 private final OutputStream stdoutConsumer;
339 private final OutputStream stderrConsumer;
340
341 @SuppressWarnings("ParameterNumber")
342 private Impl(
343 String command,
344 List<String> arguments,
345 Path cwd,
346 Path installationDirectory,
347 Path userHomeDirectory,
348 Map<String, String> jvmSystemProperties,
349 Map<String, String> environmentVariables,
350 List<String> jvmArguments,
351 OutputStream stdoutConsumer,
352 OutputStream stderrConsumer) {
353 this.command = requireNonNull(command);
354 this.arguments = arguments == null ? List.of() : List.copyOf(arguments);
355 this.cwd = getCanonicalPath(requireNonNull(cwd));
356 this.installationDirectory = getCanonicalPath(requireNonNull(installationDirectory));
357 this.userHomeDirectory = getCanonicalPath(requireNonNull(userHomeDirectory));
358 this.jvmSystemProperties = jvmSystemProperties != null ? Map.copyOf(jvmSystemProperties) : null;
359 this.environmentVariables = environmentVariables != null ? Map.copyOf(environmentVariables) : null;
360 this.jvmArguments = jvmArguments != null ? List.copyOf(jvmArguments) : null;
361 this.stdoutConsumer = stdoutConsumer;
362 this.stderrConsumer = stderrConsumer;
363 }
364
365 @Override
366 public String command() {
367 return command;
368 }
369
370 @Override
371 public List<String> arguments() {
372 return arguments;
373 }
374
375 @Override
376 public Path cwd() {
377 return cwd;
378 }
379
380 @Override
381 public Path installationDirectory() {
382 return installationDirectory;
383 }
384
385 @Override
386 public Path userHomeDirectory() {
387 return userHomeDirectory;
388 }
389
390 @Override
391 public Optional<Map<String, String>> jvmSystemProperties() {
392 return Optional.ofNullable(jvmSystemProperties);
393 }
394
395 @Override
396 public Optional<Map<String, String>> environmentVariables() {
397 return Optional.ofNullable(environmentVariables);
398 }
399
400 @Override
401 public Optional<List<String>> jvmArguments() {
402 return Optional.ofNullable(jvmArguments);
403 }
404
405 @Override
406 public Optional<OutputStream> stdoutConsumer() {
407 return Optional.ofNullable(stdoutConsumer);
408 }
409
410 @Override
411 public Optional<OutputStream> stderrConsumer() {
412 return Optional.ofNullable(stderrConsumer);
413 }
414
415 @Override
416 public String toString() {
417 return "Impl{" + "command='"
418 + command + '\'' + ", arguments="
419 + arguments + ", cwd="
420 + cwd + ", installationDirectory="
421 + installationDirectory + ", userHomeDirectory="
422 + userHomeDirectory + ", jvmSystemProperties="
423 + jvmSystemProperties + ", environmentVariables="
424 + environmentVariables + ", jvmArguments="
425 + jvmArguments + ", stdoutConsumer="
426 + stdoutConsumer + ", stderrConsumer="
427 + stderrConsumer + '}';
428 }
429 }
430 }
431
432 @Nonnull
433 static Path discoverMavenHome() {
434 String mavenHome = System.getProperty("maven.home");
435 if (mavenHome == null) {
436 throw new ExecutorException("requires maven.home Java System Property set");
437 }
438 return getCanonicalPath(Paths.get(mavenHome));
439 }
440
441 @Nonnull
442 static Path getCanonicalPath(Path path) {
443 requireNonNull(path, "path");
444 try {
445 return path.toRealPath();
446 } catch (IOException e) {
447 return getCanonicalPath(path.getParent()).resolve(path.getFileName());
448 }
449 }
450 }