1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.cling.executor.internal;
20
21 import java.nio.file.Path;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.concurrent.ConcurrentHashMap;
26
27 import org.apache.maven.api.annotations.Nullable;
28 import org.apache.maven.api.cli.Executor;
29 import org.apache.maven.api.cli.ExecutorException;
30 import org.apache.maven.api.cli.ExecutorRequest;
31 import org.apache.maven.cling.executor.ExecutorHelper;
32 import org.apache.maven.cling.executor.ExecutorTool;
33
34 import static java.util.Objects.requireNonNull;
35
36
37
38
39 public class HelperImpl implements ExecutorHelper {
40 private final Mode defaultMode;
41 private final Path installationDirectory;
42 private final ExecutorTool executorTool;
43 private final HashMap<Mode, Executor> executors;
44
45 private final ConcurrentHashMap<String, String> cache;
46
47 public HelperImpl(Mode defaultMode, @Nullable Path installationDirectory, Executor embedded, Executor forked) {
48 this.defaultMode = requireNonNull(defaultMode);
49 this.installationDirectory = installationDirectory != null
50 ? ExecutorRequest.getCanonicalPath(installationDirectory)
51 : ExecutorRequest.discoverMavenHome();
52 this.executorTool = new ToolboxTool(this);
53 this.executors = new HashMap<>();
54
55 this.executors.put(Mode.EMBEDDED, requireNonNull(embedded, "embedded"));
56 this.executors.put(Mode.FORKED, requireNonNull(forked, "forked"));
57 this.cache = new ConcurrentHashMap<>();
58 }
59
60 @Override
61 public Mode getDefaultMode() {
62 return defaultMode;
63 }
64
65 @Override
66 public ExecutorRequest.Builder executorRequest() {
67 return ExecutorRequest.mavenBuilder(installationDirectory);
68 }
69
70 @Override
71 public int execute(Mode mode, ExecutorRequest executorRequest) throws ExecutorException {
72 return getExecutor(mode, executorRequest).execute(executorRequest);
73 }
74
75 @Override
76 public String mavenVersion() {
77 return cache.computeIfAbsent("maven.version", k -> {
78 ExecutorRequest request = executorRequest().build();
79 return getExecutor(Mode.AUTO, request).mavenVersion(request);
80 });
81 }
82
83 @Override
84 public Map<String, String> dump(ExecutorRequest.Builder request) throws ExecutorException {
85 return executorTool.dump(request);
86 }
87
88 @Override
89 public String localRepository(ExecutorRequest.Builder request) throws ExecutorException {
90 return executorTool.localRepository(request);
91 }
92
93 @Override
94 public String artifactPath(ExecutorRequest.Builder request, String gav, String repositoryId)
95 throws ExecutorException {
96 return executorTool.artifactPath(request, gav, repositoryId);
97 }
98
99 @Override
100 public String metadataPath(ExecutorRequest.Builder request, String gav, String repositoryId)
101 throws ExecutorException {
102 return executorTool.metadataPath(request, gav, repositoryId);
103 }
104
105 protected Executor getExecutor(Mode mode, ExecutorRequest request) throws ExecutorException {
106 return switch (mode) {
107 case AUTO -> getExecutorByRequest(request);
108 case EMBEDDED -> executors.get(Mode.EMBEDDED);
109 case FORKED -> executors.get(Mode.FORKED);
110 };
111 }
112
113 private Executor getExecutorByRequest(ExecutorRequest request) {
114 if (request.environmentVariables().orElse(Collections.emptyMap()).isEmpty()
115 && request.jvmArguments().orElse(Collections.emptyList()).isEmpty()) {
116 return getExecutor(Mode.EMBEDDED, request);
117 } else {
118 return getExecutor(Mode.FORKED, request);
119 }
120 }
121 }