1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23
24 import java.io.File;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Objects;
32 import java.util.Optional;
33 import java.util.function.Function;
34 import java.util.function.Predicate;
35 import java.util.stream.Collectors;
36
37 import org.apache.maven.artifact.ArtifactUtils;
38 import org.apache.maven.execution.MavenSession;
39 import org.apache.maven.model.Model;
40 import org.apache.maven.project.MavenProject;
41 import org.apache.maven.repository.internal.MavenWorkspaceReader;
42 import org.eclipse.aether.artifact.Artifact;
43 import org.eclipse.aether.repository.WorkspaceRepository;
44 import org.eclipse.aether.util.artifact.ArtifactIdUtils;
45
46 import static java.util.function.Function.identity;
47 import static java.util.stream.Collectors.groupingBy;
48 import static java.util.stream.Collectors.toMap;
49
50
51
52
53
54
55
56 @Named(ReactorReader.HINT)
57 @SessionScoped
58 class ReactorReader implements MavenWorkspaceReader {
59 public static final String HINT = "reactor";
60
61 public static final String PROJECT_LOCAL_REPO = "project-local-repo";
62
63 private static final Collection<String> COMPILE_PHASE_TYPES = new HashSet<>(
64 Arrays.asList("jar", "ejb-client", "war", "rar", "ejb3", "par", "sar", "wsr", "har", "app-client"));
65
66 private final MavenSession session;
67 private final Map<String, MavenProject> projectsByGAV;
68 private final Map<String, List<MavenProject>> projectsByGA;
69 private final WorkspaceRepository repository;
70
71 private Function<MavenProject, String> projectIntoKey =
72 s -> ArtifactUtils.key(s.getGroupId(), s.getArtifactId(), s.getVersion());
73
74 private Function<MavenProject, String> projectIntoVersionlessKey =
75 s -> ArtifactUtils.versionlessKey(s.getGroupId(), s.getArtifactId());
76
77 @Inject
78 ReactorReader(MavenSession session) {
79 this.session = session;
80 this.projectsByGAV = session.getProjects().stream().collect(toMap(projectIntoKey, identity()));
81
82 this.projectsByGA = projectsByGAV.values().stream().collect(groupingBy(projectIntoVersionlessKey));
83
84 repository = new WorkspaceRepository("reactor", new HashSet<>(projectsByGAV.keySet()));
85 }
86
87
88
89
90
91 public WorkspaceRepository getRepository() {
92 return repository;
93 }
94
95 public File findArtifact(Artifact artifact) {
96 String projectKey = ArtifactUtils.key(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
97
98 MavenProject project = projectsByGAV.get(projectKey);
99
100 if (project != null) {
101 File file = find(project, artifact);
102 if (file == null && project != project.getExecutionProject()) {
103 file = find(project.getExecutionProject(), artifact);
104 }
105 return file;
106 }
107
108 return null;
109 }
110
111 public List<String> findVersions(Artifact artifact) {
112 String key = ArtifactUtils.versionlessKey(artifact.getGroupId(), artifact.getArtifactId());
113
114 return Optional.ofNullable(projectsByGA.get(key)).orElse(Collections.emptyList()).stream()
115 .filter(s -> Objects.nonNull(find(s, artifact)))
116 .map(MavenProject::getVersion)
117 .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
118 }
119
120 @Override
121 public Model findModel(Artifact artifact) {
122 String projectKey = ArtifactUtils.key(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
123 MavenProject project = projectsByGAV.get(projectKey);
124 return project == null ? null : project.getModel();
125 }
126
127
128
129
130
131 private File find(MavenProject project, Artifact artifact) {
132 if ("pom".equals(artifact.getExtension())
133 && (artifact.getClassifier() == null || artifact.getClassifier().isEmpty())) {
134 return project.getFile();
135 }
136
137 Artifact projectArtifact = findMatchingArtifact(project, artifact);
138
139 if (hasArtifactFileFromPackagePhase(projectArtifact)) {
140 return projectArtifact.getFile();
141 } else if (!hasBeenPackaged(project)) {
142
143
144
145 if (isTestArtifact(artifact)) {
146 if (project.hasLifecyclePhase("test-compile")) {
147 return new File(project.getBuild().getTestOutputDirectory());
148 }
149 } else {
150 String type = artifact.getProperty("type", "");
151 if (project.hasLifecyclePhase("compile") && COMPILE_PHASE_TYPES.contains(type)) {
152 return new File(project.getBuild().getOutputDirectory());
153 }
154 }
155 }
156
157
158
159 return null;
160 }
161
162 private File determinePreviouslyPackagedArtifactFile(MavenProject project, Artifact artifact) {
163 if (artifact == null) {
164 return null;
165 }
166
167 String fileName = String.format("%s.%s", project.getBuild().getFinalName(), artifact.getExtension());
168 return new File(project.getBuild().getDirectory(), fileName);
169 }
170
171 private boolean hasArtifactFileFromPackagePhase(Artifact projectArtifact) {
172 return projectArtifact != null
173 && projectArtifact.getFile() != null
174 && projectArtifact.getFile().exists();
175 }
176
177 private boolean hasBeenPackaged(MavenProject project) {
178 return project.hasLifecyclePhase("package")
179 || project.hasLifecyclePhase("install")
180 || project.hasLifecyclePhase("deploy");
181 }
182
183
184
185
186
187
188
189
190 private Artifact findMatchingArtifact(MavenProject project, Artifact requestedArtifact) {
191 String requestedRepositoryConflictId = ArtifactIdUtils.toVersionlessId(requestedArtifact);
192
193 Artifact mainArtifact = RepositoryUtils.toArtifact(project.getArtifact());
194 if (requestedRepositoryConflictId.equals(ArtifactIdUtils.toVersionlessId(mainArtifact))) {
195 return mainArtifact;
196 }
197
198 return RepositoryUtils.toArtifacts(project.getAttachedArtifacts()).stream()
199 .filter(isRequestedArtifact(requestedArtifact))
200 .findFirst()
201 .orElse(null);
202 }
203
204
205
206
207
208
209
210
211 private Predicate<Artifact> isRequestedArtifact(Artifact requestArtifact) {
212 return s -> s.getArtifactId().equals(requestArtifact.getArtifactId())
213 && s.getGroupId().equals(requestArtifact.getGroupId())
214 && s.getVersion().equals(requestArtifact.getVersion())
215 && s.getExtension().equals(requestArtifact.getExtension())
216 && s.getClassifier().equals(requestArtifact.getClassifier());
217 }
218
219
220
221
222
223
224
225 private static boolean isTestArtifact(Artifact artifact) {
226 return ("test-jar".equals(artifact.getProperty("type", "")))
227 || ("jar".equals(artifact.getExtension()) && "tests".equals(artifact.getClassifier()));
228 }
229 }