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.InputStream;
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 Optional<InputStream> stdIn();
127
128
129
130
131
132
133
134
135 Optional<OutputStream> stdOut();
136
137
138
139
140
141
142
143
144 Optional<OutputStream> stdErr();
145
146
147
148
149
150
151 boolean skipMavenRc();
152
153
154
155
156 @Nonnull
157 default Builder toBuilder() {
158 return new Builder(
159 command(),
160 arguments(),
161 cwd(),
162 installationDirectory(),
163 userHomeDirectory(),
164 jvmSystemProperties().orElse(null),
165 environmentVariables().orElse(null),
166 jvmArguments().orElse(null),
167 stdIn().orElse(null),
168 stdOut().orElse(null),
169 stdErr().orElse(null),
170 skipMavenRc());
171 }
172
173
174
175
176
177 @Nonnull
178 static Builder mavenBuilder(@Nullable Path installationDirectory) {
179 return new Builder(
180 MVN,
181 null,
182 getCanonicalPath(Paths.get(System.getProperty("user.dir"))),
183 installationDirectory != null
184 ? getCanonicalPath(installationDirectory)
185 : discoverInstallationDirectory(),
186 getCanonicalPath(Paths.get(System.getProperty("user.home"))),
187 null,
188 null,
189 null,
190 null,
191 null,
192 null,
193 false);
194 }
195
196 class Builder {
197 private String command;
198 private List<String> arguments;
199 private Path cwd;
200 private Path installationDirectory;
201 private Path userHomeDirectory;
202 private Map<String, String> jvmSystemProperties;
203 private Map<String, String> environmentVariables;
204 private List<String> jvmArguments;
205 private InputStream stdIn;
206 private OutputStream stdOut;
207 private OutputStream stdErr;
208 private boolean skipMavenRc;
209
210 private Builder() {}
211
212 @SuppressWarnings("ParameterNumber")
213 private Builder(
214 String command,
215 List<String> arguments,
216 Path cwd,
217 Path installationDirectory,
218 Path userHomeDirectory,
219 Map<String, String> jvmSystemProperties,
220 Map<String, String> environmentVariables,
221 List<String> jvmArguments,
222 InputStream stdIn,
223 OutputStream stdOut,
224 OutputStream stdErr,
225 boolean skipMavenRc) {
226 this.command = command;
227 this.arguments = arguments;
228 this.cwd = cwd;
229 this.installationDirectory = installationDirectory;
230 this.userHomeDirectory = userHomeDirectory;
231 this.jvmSystemProperties = jvmSystemProperties;
232 this.environmentVariables = environmentVariables;
233 this.jvmArguments = jvmArguments;
234 this.stdIn = stdIn;
235 this.stdOut = stdOut;
236 this.stdErr = stdErr;
237 this.skipMavenRc = skipMavenRc;
238 }
239
240 @Nonnull
241 public Builder command(String command) {
242 this.command = requireNonNull(command, "command");
243 return this;
244 }
245
246 @Nonnull
247 public Builder arguments(List<String> arguments) {
248 this.arguments = requireNonNull(arguments, "arguments");
249 return this;
250 }
251
252 @Nonnull
253 public Builder argument(String argument) {
254 if (arguments == null) {
255 arguments = new ArrayList<>();
256 }
257 this.arguments.add(requireNonNull(argument, "argument"));
258 return this;
259 }
260
261 @Nonnull
262 public Builder cwd(Path cwd) {
263 this.cwd = getCanonicalPath(requireNonNull(cwd, "cwd"));
264 return this;
265 }
266
267 @Nonnull
268 public Builder installationDirectory(Path installationDirectory) {
269 this.installationDirectory =
270 getCanonicalPath(requireNonNull(installationDirectory, "installationDirectory"));
271 return this;
272 }
273
274 @Nonnull
275 public Builder userHomeDirectory(Path userHomeDirectory) {
276 this.userHomeDirectory = getCanonicalPath(requireNonNull(userHomeDirectory, "userHomeDirectory"));
277 return this;
278 }
279
280 @Nonnull
281 public Builder jvmSystemProperties(Map<String, String> jvmSystemProperties) {
282 this.jvmSystemProperties = jvmSystemProperties;
283 return this;
284 }
285
286 @Nonnull
287 public Builder jvmSystemProperty(String key, String value) {
288 requireNonNull(key, "env key");
289 requireNonNull(value, "env value");
290 if (jvmSystemProperties == null) {
291 this.jvmSystemProperties = new HashMap<>();
292 }
293 this.jvmSystemProperties.put(key, value);
294 return this;
295 }
296
297 @Nonnull
298 public Builder environmentVariables(Map<String, String> environmentVariables) {
299 this.environmentVariables = environmentVariables;
300 return this;
301 }
302
303 @Nonnull
304 public Builder environmentVariable(String key, String value) {
305 requireNonNull(key, "env key");
306 requireNonNull(value, "env value");
307 if (environmentVariables == null) {
308 this.environmentVariables = new HashMap<>();
309 }
310 this.environmentVariables.put(key, value);
311 return this;
312 }
313
314 @Nonnull
315 public Builder jvmArguments(List<String> jvmArguments) {
316 this.jvmArguments = jvmArguments;
317 return this;
318 }
319
320 @Nonnull
321 public Builder jvmArgument(String jvmArgument) {
322 if (jvmArguments == null) {
323 jvmArguments = new ArrayList<>();
324 }
325 this.jvmArguments.add(requireNonNull(jvmArgument, "jvmArgument"));
326 return this;
327 }
328
329 @Nonnull
330 public Builder stdIn(InputStream stdIn) {
331 this.stdIn = stdIn;
332 return this;
333 }
334
335 @Nonnull
336 public Builder stdOut(OutputStream stdOut) {
337 this.stdOut = stdOut;
338 return this;
339 }
340
341 @Nonnull
342 public Builder stdErr(OutputStream stdErr) {
343 this.stdErr = stdErr;
344 return this;
345 }
346
347 @Nonnull
348 public Builder skipMavenRc(boolean skipMavenRc) {
349 this.skipMavenRc = skipMavenRc;
350 return this;
351 }
352
353 @Nonnull
354 public ExecutorRequest build() {
355 return new Impl(
356 command,
357 arguments,
358 cwd,
359 installationDirectory,
360 userHomeDirectory,
361 jvmSystemProperties,
362 environmentVariables,
363 jvmArguments,
364 stdIn,
365 stdOut,
366 stdErr,
367 skipMavenRc);
368 }
369
370 private static class Impl implements ExecutorRequest {
371 private final String command;
372 private final List<String> arguments;
373 private final Path cwd;
374 private final Path installationDirectory;
375 private final Path userHomeDirectory;
376 private final Map<String, String> jvmSystemProperties;
377 private final Map<String, String> environmentVariables;
378 private final List<String> jvmArguments;
379 private final InputStream stdIn;
380 private final OutputStream stdOut;
381 private final OutputStream stdErr;
382 private final boolean skipMavenRc;
383
384 @SuppressWarnings("ParameterNumber")
385 private Impl(
386 String command,
387 List<String> arguments,
388 Path cwd,
389 Path installationDirectory,
390 Path userHomeDirectory,
391 Map<String, String> jvmSystemProperties,
392 Map<String, String> environmentVariables,
393 List<String> jvmArguments,
394 InputStream stdIn,
395 OutputStream stdOut,
396 OutputStream stdErr,
397 boolean skipMavenRc) {
398 this.command = requireNonNull(command);
399 this.arguments = arguments == null ? List.of() : List.copyOf(arguments);
400 this.cwd = getCanonicalPath(requireNonNull(cwd));
401 this.installationDirectory = getCanonicalPath(requireNonNull(installationDirectory));
402 this.userHomeDirectory = getCanonicalPath(requireNonNull(userHomeDirectory));
403 this.jvmSystemProperties = jvmSystemProperties != null && !jvmSystemProperties.isEmpty()
404 ? Map.copyOf(jvmSystemProperties)
405 : null;
406 this.environmentVariables = environmentVariables != null && !environmentVariables.isEmpty()
407 ? Map.copyOf(environmentVariables)
408 : null;
409 this.jvmArguments = jvmArguments != null && !jvmArguments.isEmpty() ? List.copyOf(jvmArguments) : null;
410 this.stdIn = stdIn;
411 this.stdOut = stdOut;
412 this.stdErr = stdErr;
413 this.skipMavenRc = skipMavenRc;
414 }
415
416 @Override
417 public String command() {
418 return command;
419 }
420
421 @Override
422 public List<String> arguments() {
423 return arguments;
424 }
425
426 @Override
427 public Path cwd() {
428 return cwd;
429 }
430
431 @Override
432 public Path installationDirectory() {
433 return installationDirectory;
434 }
435
436 @Override
437 public Path userHomeDirectory() {
438 return userHomeDirectory;
439 }
440
441 @Override
442 public Optional<Map<String, String>> jvmSystemProperties() {
443 return Optional.ofNullable(jvmSystemProperties);
444 }
445
446 @Override
447 public Optional<Map<String, String>> environmentVariables() {
448 return Optional.ofNullable(environmentVariables);
449 }
450
451 @Override
452 public Optional<List<String>> jvmArguments() {
453 return Optional.ofNullable(jvmArguments);
454 }
455
456 @Override
457 public Optional<InputStream> stdIn() {
458 return Optional.ofNullable(stdIn);
459 }
460
461 @Override
462 public Optional<OutputStream> stdOut() {
463 return Optional.ofNullable(stdOut);
464 }
465
466 @Override
467 public Optional<OutputStream> stdErr() {
468 return Optional.ofNullable(stdErr);
469 }
470
471 @Override
472 public boolean skipMavenRc() {
473 return skipMavenRc;
474 }
475
476 @Override
477 public String toString() {
478 return getClass().getSimpleName() + "{" + "command='"
479 + command + '\'' + ", arguments="
480 + arguments + ", cwd="
481 + cwd + ", installationDirectory="
482 + installationDirectory + ", userHomeDirectory="
483 + userHomeDirectory + ", jvmSystemProperties="
484 + jvmSystemProperties + ", environmentVariables="
485 + environmentVariables + ", jvmArguments="
486 + jvmArguments + ", stdinProvider="
487 + stdIn + ", stdoutConsumer="
488 + stdOut + ", stderrConsumer="
489 + stdErr + ", skipMavenRc="
490 + skipMavenRc + "}";
491 }
492 }
493 }
494
495 @Nonnull
496 static Path discoverInstallationDirectory() {
497 String mavenHome = System.getProperty("maven.home");
498 if (mavenHome == null) {
499 throw new ExecutorException("requires maven.home Java System Property set");
500 }
501 return getCanonicalPath(Paths.get(mavenHome));
502 }
503
504 @Nonnull
505 static Path discoverUserHomeDirectory() {
506 String userHome = System.getProperty("user.home");
507 if (userHome == null) {
508 throw new ExecutorException("requires user.home Java System Property set");
509 }
510 return getCanonicalPath(Paths.get(userHome));
511 }
512
513 @Nonnull
514 static Path getCanonicalPath(Path path) {
515 requireNonNull(path, "path");
516 return path.toAbsolutePath().normalize();
517 }
518 }