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