1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.project;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.ByteArrayInputStream;
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.nio.charset.StandardCharsets;
30 import java.nio.file.Path;
31 import java.util.AbstractMap;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.HashSet;
36 import java.util.LinkedHashSet;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Objects;
40 import java.util.Properties;
41 import java.util.Set;
42 import java.util.concurrent.ConcurrentHashMap;
43 import java.util.function.Supplier;
44 import java.util.stream.Collectors;
45 import java.util.stream.Stream;
46
47 import org.apache.maven.ProjectCycleException;
48 import org.apache.maven.RepositoryUtils;
49 import org.apache.maven.api.SessionData;
50 import org.apache.maven.api.model.Build;
51 import org.apache.maven.api.model.Dependency;
52 import org.apache.maven.api.model.DependencyManagement;
53 import org.apache.maven.api.model.DeploymentRepository;
54 import org.apache.maven.api.model.Extension;
55 import org.apache.maven.api.model.Model;
56 import org.apache.maven.api.model.Plugin;
57 import org.apache.maven.api.model.Profile;
58 import org.apache.maven.api.model.ReportPlugin;
59 import org.apache.maven.api.services.BuilderProblem.Severity;
60 import org.apache.maven.api.services.ModelBuilder;
61 import org.apache.maven.api.services.ModelBuilderException;
62 import org.apache.maven.api.services.ModelBuilderRequest;
63 import org.apache.maven.api.services.ModelBuilderResult;
64 import org.apache.maven.api.services.ModelProblem;
65 import org.apache.maven.api.services.ModelProblem.Version;
66 import org.apache.maven.api.services.ModelProblemCollector;
67 import org.apache.maven.api.services.ModelSource;
68 import org.apache.maven.api.services.ModelTransformer;
69 import org.apache.maven.api.services.Source;
70 import org.apache.maven.api.services.model.LifecycleBindingsInjector;
71 import org.apache.maven.artifact.Artifact;
72 import org.apache.maven.artifact.InvalidRepositoryException;
73 import org.apache.maven.artifact.repository.ArtifactRepository;
74 import org.apache.maven.bridge.MavenRepositorySystem;
75 import org.apache.maven.internal.impl.InternalSession;
76 import org.apache.maven.internal.impl.resolver.ArtifactDescriptorUtils;
77 import org.apache.maven.model.building.DefaultModelProblem;
78 import org.apache.maven.model.building.FileModelSource;
79 import org.apache.maven.model.building.ModelBuildingRequest;
80 import org.apache.maven.model.building.ModelSource2;
81 import org.apache.maven.model.building.ModelSource3;
82 import org.apache.maven.model.root.RootLocator;
83 import org.apache.maven.plugin.PluginManagerException;
84 import org.apache.maven.plugin.PluginResolutionException;
85 import org.apache.maven.plugin.version.PluginVersionResolutionException;
86 import org.eclipse.aether.RepositorySystem;
87 import org.eclipse.aether.RepositorySystemSession;
88 import org.eclipse.aether.repository.LocalRepositoryManager;
89 import org.eclipse.aether.repository.WorkspaceRepository;
90 import org.eclipse.aether.resolution.ArtifactRequest;
91 import org.eclipse.aether.resolution.ArtifactResult;
92 import org.slf4j.Logger;
93 import org.slf4j.LoggerFactory;
94
95
96
97
98 @Named
99 @Singleton
100 public class DefaultProjectBuilder implements ProjectBuilder {
101
102 private final Logger logger = LoggerFactory.getLogger(getClass());
103 private final ModelBuilder modelBuilder;
104 private final ProjectBuildingHelper projectBuildingHelper;
105 private final MavenRepositorySystem repositorySystem;
106 private final org.eclipse.aether.RepositorySystem repoSystem;
107 private final ProjectDependenciesResolver dependencyResolver;
108 private final RootLocator rootLocator;
109 private final LifecycleBindingsInjector lifecycleBindingsInjector;
110
111 @SuppressWarnings("checkstyle:ParameterNumber")
112 @Inject
113 public DefaultProjectBuilder(
114 ModelBuilder modelBuilder,
115 ProjectBuildingHelper projectBuildingHelper,
116 MavenRepositorySystem repositorySystem,
117 RepositorySystem repoSystem,
118 ProjectDependenciesResolver dependencyResolver,
119 RootLocator rootLocator,
120 LifecycleBindingsInjector lifecycleBindingsInjector) {
121 this.modelBuilder = modelBuilder;
122 this.projectBuildingHelper = projectBuildingHelper;
123 this.repositorySystem = repositorySystem;
124 this.repoSystem = repoSystem;
125 this.dependencyResolver = dependencyResolver;
126 this.rootLocator = rootLocator;
127 this.lifecycleBindingsInjector = lifecycleBindingsInjector;
128 }
129
130
131
132
133 @Override
134 public ProjectBuildingResult build(File pomFile, ProjectBuildingRequest request) throws ProjectBuildingException {
135 try (BuildSession bs = new BuildSession(request)) {
136 Path path = pomFile.toPath();
137 return bs.build(path, ModelSource.fromPath(path));
138 }
139 }
140
141 @Deprecated
142 @Override
143 public ProjectBuildingResult build(
144 org.apache.maven.model.building.ModelSource modelSource, ProjectBuildingRequest request)
145 throws ProjectBuildingException {
146 return build(toSource(modelSource), request);
147 }
148
149 @Deprecated
150 static ModelSource toSource(org.apache.maven.model.building.ModelSource modelSource) {
151 if (modelSource instanceof FileModelSource fms) {
152 return ModelSource.fromPath(fms.getPath());
153 } else {
154 return new WrapModelSource(modelSource);
155 }
156 }
157
158 @Override
159 public ProjectBuildingResult build(ModelSource modelSource, ProjectBuildingRequest request)
160 throws ProjectBuildingException {
161 try (BuildSession bs = new BuildSession(request)) {
162 return bs.build(null, modelSource);
163 }
164 }
165
166 @Override
167 public ProjectBuildingResult build(Artifact artifact, ProjectBuildingRequest request)
168 throws ProjectBuildingException {
169 return build(artifact, false, request);
170 }
171
172 @Override
173 public ProjectBuildingResult build(Artifact artifact, boolean allowStubModel, ProjectBuildingRequest request)
174 throws ProjectBuildingException {
175 try (BuildSession bs = new BuildSession(request)) {
176 return bs.build(artifact, allowStubModel);
177 }
178 }
179
180 @Override
181 public List<ProjectBuildingResult> build(List<File> pomFiles, boolean recursive, ProjectBuildingRequest request)
182 throws ProjectBuildingException {
183 try (BuildSession bs = new BuildSession(request)) {
184 return bs.build(pomFiles, recursive);
185 }
186 }
187
188 private static class StubModelSource implements ModelSource {
189 private final String xml;
190 private final Artifact artifact;
191
192 StubModelSource(String xml, Artifact artifact) {
193 this.xml = xml;
194 this.artifact = artifact;
195 }
196
197 @Override
198 public ModelSource resolve(ModelLocator modelLocator, String relative) {
199 return null;
200 }
201
202 @Override
203 public Path getPath() {
204 return null;
205 }
206
207 @Override
208 public InputStream openStream() throws IOException {
209 return new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
210 }
211
212 @Override
213 public String getLocation() {
214 return artifact.getId();
215 }
216
217 @Override
218 public Source resolve(String relative) {
219 return null;
220 }
221
222 @Override
223 public boolean equals(Object o) {
224 if (this == o) {
225 return true;
226 }
227 if (o == null || getClass() != o.getClass()) {
228 return false;
229 }
230 StubModelSource that = (StubModelSource) o;
231 return Objects.equals(xml, that.xml) && Objects.equals(artifact, that.artifact);
232 }
233
234 @Override
235 public int hashCode() {
236 return Objects.hash(xml, artifact);
237 }
238 }
239
240 private static class WrapModelSource implements ModelSource {
241 private final org.apache.maven.model.building.ModelSource modelSource;
242
243 WrapModelSource(org.apache.maven.model.building.ModelSource modelSource) {
244 this.modelSource = modelSource;
245 }
246
247 @Override
248 public ModelSource resolve(ModelLocator modelLocator, String relative) {
249 if (modelSource instanceof ModelSource3 ms) {
250 return toSource(ms.getRelatedSource(
251 new org.apache.maven.model.locator.ModelLocator() {
252 @Override
253 public File locatePom(File projectDirectory) {
254 return null;
255 }
256
257 @Override
258 public Path locatePom(Path projectDirectory) {
259 return null;
260 }
261
262 @Override
263 public Path locateExistingPom(Path project) {
264 return modelLocator.locateExistingPom(project);
265 }
266 },
267 relative));
268 }
269 return null;
270 }
271
272 @Override
273 public Path getPath() {
274 return null;
275 }
276
277 @Override
278 public InputStream openStream() throws IOException {
279 return modelSource.getInputStream();
280 }
281
282 @Override
283 public String getLocation() {
284 return modelSource.getLocation();
285 }
286
287 @Override
288 public Source resolve(String relative) {
289 if (modelSource instanceof ModelSource2 ms) {
290 return toSource(ms.getRelatedSource(relative));
291 } else {
292 return null;
293 }
294 }
295
296 @Override
297 public boolean equals(Object o) {
298 if (this == o) {
299 return true;
300 }
301 if (o == null || getClass() != o.getClass()) {
302 return false;
303 }
304 WrapModelSource that = (WrapModelSource) o;
305 return Objects.equals(modelSource, that.modelSource);
306 }
307
308 @Override
309 public int hashCode() {
310 return Objects.hashCode(modelSource);
311 }
312 }
313
314 class BuildSession implements AutoCloseable {
315 private final ProjectBuildingRequest request;
316 private final RepositorySystemSession session;
317 private final ModelBuilder.ModelBuilderSession modelBuilderSession;
318 private final Map<String, MavenProject> projectIndex = new ConcurrentHashMap<>(256);
319
320 BuildSession(ProjectBuildingRequest request) {
321 this.request = request;
322 this.session =
323 RepositoryUtils.overlay(request.getLocalRepository(), request.getRepositorySession(), repoSystem);
324 InternalSession iSession = InternalSession.from(session);
325 this.modelBuilderSession = modelBuilder.newSession();
326
327
328
329
330 iSession.getData()
331 .replace(SessionData.key(ModelBuilder.ModelBuilderSession.class), null, modelBuilderSession);
332 }
333
334 @Override
335 public void close() {}
336
337 ProjectBuildingResult build(Path pomFile, ModelSource modelSource) throws ProjectBuildingException {
338 ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
339
340 try {
341 MavenProject project = request.getProject();
342
343 List<ModelProblem> modelProblems = null;
344 Throwable error = null;
345
346 if (project == null) {
347 project = new MavenProject();
348 project.setFile(pomFile != null ? pomFile.toFile() : null);
349
350 ModelBuilderRequest.ModelBuilderRequestBuilder builder = getModelBuildingRequest();
351 ModelBuilderRequest.RequestType type = pomFile != null
352 && this.request.isProcessPlugins()
353 && this.request.getValidationLevel() == ModelBuildingRequest.VALIDATION_LEVEL_STRICT
354 ? ModelBuilderRequest.RequestType.BUILD_EFFECTIVE
355 : ModelBuilderRequest.RequestType.CONSUMER_PARENT;
356 MavenProject theProject = project;
357 ModelBuilderRequest request = builder.source(modelSource)
358 .requestType(type)
359 .locationTracking(true)
360 .lifecycleBindingsInjector(
361 (m, r, p) -> injectLifecycleBindings(m, r, p, theProject, this.request))
362 .build();
363
364 if (pomFile != null) {
365 project.setRootDirectory(rootLocator.findRoot(pomFile.getParent()));
366 }
367
368 ModelBuilderResult result;
369 try {
370 result = modelBuilderSession.build(request);
371 } catch (ModelBuilderException e) {
372 result = e.getResult();
373 if (result == null || result.getEffectiveModel() == null) {
374 throw new ProjectBuildingException(
375 e.getModelId(), e.getMessage(), pomFile != null ? pomFile.toFile() : null, e);
376 }
377
378 error = e;
379 }
380
381 modelProblems = result.getProblems();
382
383 initProject(project, result);
384 }
385
386 DependencyResolutionResult resolutionResult = null;
387
388 if (request.isResolveDependencies()) {
389 projectBuildingHelper.selectProjectRealm(project);
390 resolutionResult = resolveDependencies(project);
391 }
392
393 ProjectBuildingResult result =
394 new DefaultProjectBuildingResult(project, convert(modelProblems), resolutionResult);
395
396 if (error != null) {
397 ProjectBuildingException e = new ProjectBuildingException(List.of(result));
398 e.initCause(error);
399 throw e;
400 }
401
402 return result;
403 } finally {
404 Thread.currentThread().setContextClassLoader(oldContextClassLoader);
405 }
406 }
407
408 ProjectBuildingResult build(Artifact artifact, boolean allowStubModel) throws ProjectBuildingException {
409 org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact(artifact);
410 pomArtifact = ArtifactDescriptorUtils.toPomArtifact(pomArtifact);
411
412 boolean localProject;
413
414 try {
415 ArtifactRequest pomRequest = new ArtifactRequest();
416 pomRequest.setArtifact(pomArtifact);
417 pomRequest.setRepositories(RepositoryUtils.toRepos(request.getRemoteRepositories()));
418 ArtifactResult pomResult = repoSystem.resolveArtifact(session, pomRequest);
419
420 pomArtifact = pomResult.getArtifact();
421 localProject = pomResult.getRepository() instanceof WorkspaceRepository;
422 } catch (org.eclipse.aether.resolution.ArtifactResolutionException e) {
423 if (e.getResults().get(0).isMissing() && allowStubModel) {
424 return build(null, createStubModelSource(artifact));
425 }
426 throw new ProjectBuildingException(
427 artifact.getId(), "Error resolving project artifact: " + e.getMessage(), e);
428 }
429
430 Path pomFile = pomArtifact.getPath();
431
432 if (!artifact.isResolved() && "pom".equals(artifact.getType())) {
433 artifact.selectVersion(pomArtifact.getVersion());
434 artifact.setFile(pomFile.toFile());
435 artifact.setResolved(true);
436 }
437
438 if (localProject) {
439 return build(pomFile, ModelSource.fromPath(pomFile));
440 } else {
441 return build(
442 null,
443 ModelSource.fromPath(
444 pomFile,
445 artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion()));
446 }
447 }
448
449 List<ProjectBuildingResult> build(List<File> pomFiles, boolean recursive) throws ProjectBuildingException {
450 List<ProjectBuildingResult> results = doBuild(pomFiles, recursive);
451 if (results.stream()
452 .flatMap(r -> r.getProblems().stream())
453 .anyMatch(p -> p.getSeverity() != org.apache.maven.model.building.ModelProblem.Severity.WARNING)) {
454 org.apache.maven.model.building.ModelProblem cycle = results.stream()
455 .flatMap(r -> r.getProblems().stream())
456 .filter(p -> p.getException() instanceof CycleDetectedException)
457 .findAny()
458 .orElse(null);
459 if (cycle != null) {
460 throw new RuntimeException(new ProjectCycleException(
461 "The projects in the reactor contain a cyclic reference: " + cycle.getMessage(),
462 (CycleDetectedException) cycle.getException()));
463 }
464 throw new ProjectBuildingException(results);
465 }
466
467 return results;
468 }
469
470 List<ProjectBuildingResult> doBuild(List<File> pomFiles, boolean recursive) {
471 ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
472 try {
473 return pomFiles.stream()
474 .map(pomFile -> build(pomFile, recursive))
475 .flatMap(List::stream)
476 .collect(Collectors.toList());
477 } finally {
478 Thread.currentThread().setContextClassLoader(oldContextClassLoader);
479 }
480 }
481
482 @SuppressWarnings("checkstyle:parameternumber")
483 private List<ProjectBuildingResult> build(File pomFile, boolean recursive) {
484 ModelBuilderResult result;
485 try {
486 ModelTransformer injector = (m, r, p) -> {
487 MavenProject project = projectIndex.computeIfAbsent(m.getId(), f -> new MavenProject());
488 return injectLifecycleBindings(m, r, p, project, request);
489 };
490 ModelBuilderRequest modelBuildingRequest = getModelBuildingRequest()
491 .source(ModelSource.fromPath(pomFile.toPath()))
492 .requestType(ModelBuilderRequest.RequestType.BUILD_PROJECT)
493 .locationTracking(true)
494 .recursive(recursive)
495 .lifecycleBindingsInjector(injector)
496 .build();
497 result = modelBuilderSession.build(modelBuildingRequest);
498 } catch (ModelBuilderException e) {
499 result = e.getResult();
500 if (result == null || result.getEffectiveModel() == null) {
501 return List.of(new DefaultProjectBuildingResult(e.getModelId(), pomFile, convert(e.getProblems())));
502 }
503 }
504
505 List<ProjectBuildingResult> results = new ArrayList<>();
506 List<ModelBuilderResult> allModels = results(result).toList();
507 for (ModelBuilderResult r : allModels) {
508 List<ModelProblem> problems = new ArrayList<>(r.getProblems());
509 results(r)
510 .filter(c -> c != r)
511 .flatMap(c -> c.getProblems().stream())
512 .forEach(problems::remove);
513 if (r.getEffectiveModel() != null) {
514 File pom = r.getSource().getPath().toFile();
515 MavenProject project =
516 projectIndex.get(r.getEffectiveModel().getId());
517 Path rootDirectory =
518 rootLocator.findRoot(pom.getParentFile().toPath());
519 project.setRootDirectory(rootDirectory);
520 project.setFile(pom);
521 project.setExecutionRoot(pom.equals(pomFile));
522 initProject(project, r);
523 project.setCollectedProjects(results(r)
524 .filter(cr -> cr != r && cr.getEffectiveModel() != null)
525 .map(cr -> projectIndex.get(cr.getEffectiveModel().getId()))
526 .collect(Collectors.toList()));
527
528 DependencyResolutionResult resolutionResult = null;
529 if (request.isResolveDependencies()) {
530 resolutionResult = resolveDependencies(project);
531 }
532 results.add(new DefaultProjectBuildingResult(project, convert(problems), resolutionResult));
533 } else {
534 results.add(new DefaultProjectBuildingResult(null, convert(problems), null));
535 }
536 }
537 return results;
538 }
539
540 private Stream<ModelBuilderResult> results(ModelBuilderResult result) {
541 return Stream.concat(result.getChildren().stream().flatMap(this::results), Stream.of(result));
542 }
543
544 private List<org.apache.maven.model.building.ModelProblem> convert(List<ModelProblem> problems) {
545 if (problems == null) {
546 return null;
547 }
548 return problems.stream().map(p -> convert(p)).toList();
549 }
550
551 private static org.apache.maven.model.building.ModelProblem convert(ModelProblem p) {
552 return new DefaultModelProblem(
553 p.getMessage(),
554 org.apache.maven.model.building.ModelProblem.Severity.valueOf(
555 p.getSeverity().name()),
556 org.apache.maven.model.building.ModelProblem.Version.valueOf(
557 p.getVersion().name()),
558 p.getSource(),
559 p.getLineNumber(),
560 p.getColumnNumber(),
561 p.getModelId(),
562 p.getException());
563 }
564
565 @SuppressWarnings({"checkstyle:methodlength", "deprecation"})
566 private void initProject(MavenProject project, ModelBuilderResult result) {
567 project.setModel(new org.apache.maven.model.Model(result.getEffectiveModel()));
568 project.setOriginalModel(new org.apache.maven.model.Model(result.getFileModel()));
569
570 initParent(project, result);
571
572 Artifact projectArtifact = repositorySystem.createArtifact(
573 project.getGroupId(), project.getArtifactId(), project.getVersion(), null, project.getPackaging());
574 project.setArtifact(projectArtifact);
575
576
577 if (project.getFile() != null) {
578 Build build = project.getBuild().getDelegate();
579 project.addScriptSourceRoot(build.getScriptSourceDirectory());
580 project.addCompileSourceRoot(build.getSourceDirectory());
581 project.addTestCompileSourceRoot(build.getTestSourceDirectory());
582 }
583
584 project.setActiveProfiles(
585 Stream.concat(result.getActivePomProfiles().stream(), result.getActiveExternalProfiles().stream())
586 .map(org.apache.maven.model.Profile::new)
587 .toList());
588
589 project.setInjectedProfileIds("external", getProfileIds(result.getActiveExternalProfiles()));
590 project.setInjectedProfileIds(
591 result.getEffectiveModel().getId(), getProfileIds(result.getActivePomProfiles()));
592
593
594
595
596
597 project.setProjectBuildingRequest(request);
598
599
600 Set<Artifact> pluginArtifacts = new HashSet<>();
601 for (Plugin plugin : project.getModel().getDelegate().getBuild().getPlugins()) {
602 Artifact artifact = repositorySystem.createPluginArtifact(new org.apache.maven.model.Plugin(plugin));
603
604 if (artifact != null) {
605 pluginArtifacts.add(artifact);
606 }
607 }
608 project.setPluginArtifacts(pluginArtifacts);
609
610
611 Set<Artifact> reportArtifacts = new HashSet<>();
612 for (ReportPlugin report :
613 project.getModel().getDelegate().getReporting().getPlugins()) {
614 Plugin pp = Plugin.newBuilder()
615 .groupId(report.getGroupId())
616 .artifactId(report.getArtifactId())
617 .version(report.getVersion())
618 .build();
619
620 Artifact artifact = repositorySystem.createPluginArtifact(new org.apache.maven.model.Plugin(pp));
621
622 if (artifact != null) {
623 reportArtifacts.add(artifact);
624 }
625 }
626 project.setReportArtifacts(reportArtifacts);
627
628
629 Set<Artifact> extensionArtifacts = new HashSet<>();
630 List<Extension> extensions =
631 project.getModel().getDelegate().getBuild().getExtensions();
632 if (extensions != null) {
633 for (Extension ext : extensions) {
634 String version;
635 if (ext.getVersion() == null || ext.getVersion().isEmpty()) {
636 version = "RELEASE";
637 } else {
638 version = ext.getVersion();
639 }
640
641 Artifact artifact = repositorySystem.createArtifact(
642 ext.getGroupId(), ext.getArtifactId(), version, null, "jar");
643
644 if (artifact != null) {
645 extensionArtifacts.add(artifact);
646 }
647 }
648 }
649 project.setExtensionArtifacts(extensionArtifacts);
650
651
652 Map<String, Artifact> map = Collections.emptyMap();
653 final DependencyManagement dependencyManagement =
654 project.getModel().getDelegate().getDependencyManagement();
655 if (dependencyManagement != null
656 && dependencyManagement.getDependencies() != null
657 && !dependencyManagement.getDependencies().isEmpty()) {
658 map = new LazyMap<>(() -> {
659 Map<String, Artifact> tmp = new HashMap<>();
660 for (Dependency d : dependencyManagement.getDependencies()) {
661 Artifact artifact =
662 repositorySystem.createDependencyArtifact(new org.apache.maven.model.Dependency(d));
663 if (artifact != null) {
664 tmp.put(d.getManagementKey(), artifact);
665 }
666 }
667 return Collections.unmodifiableMap(tmp);
668 });
669 }
670 project.setManagedVersionMap(map);
671
672
673 if (project.getDistributionManagement() != null
674 && project.getDistributionManagement().getRepository() != null) {
675 try {
676 DeploymentRepository r = project.getModel()
677 .getDelegate()
678 .getDistributionManagement()
679 .getRepository();
680 if (r.getId() != null
681 && !r.getId().isEmpty()
682 && r.getUrl() != null
683 && !r.getUrl().isEmpty()) {
684 ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository(
685 new org.apache.maven.model.DeploymentRepository(r));
686 repositorySystem.injectProxy(request.getRepositorySession(), List.of(repo));
687 repositorySystem.injectAuthentication(request.getRepositorySession(), List.of(repo));
688 project.setReleaseArtifactRepository(repo);
689 }
690 } catch (InvalidRepositoryException e) {
691 throw new IllegalStateException(
692 "Failed to create release distribution repository for " + project.getId(), e);
693 }
694 }
695
696
697 if (project.getDistributionManagement() != null
698 && project.getDistributionManagement().getSnapshotRepository() != null) {
699 try {
700 DeploymentRepository r = project.getModel()
701 .getDelegate()
702 .getDistributionManagement()
703 .getSnapshotRepository();
704 if (r.getId() != null
705 && !r.getId().isEmpty()
706 && r.getUrl() != null
707 && !r.getUrl().isEmpty()) {
708 ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository(
709 new org.apache.maven.model.DeploymentRepository(r));
710 repositorySystem.injectProxy(request.getRepositorySession(), List.of(repo));
711 repositorySystem.injectAuthentication(request.getRepositorySession(), List.of(repo));
712 project.setSnapshotArtifactRepository(repo);
713 }
714 } catch (InvalidRepositoryException e) {
715 throw new IllegalStateException(
716 "Failed to create snapshot distribution repository for " + project.getId(), e);
717 }
718 }
719 }
720
721 private void initParent(MavenProject project, ModelBuilderResult result) {
722 Model parentModel = result.getParentModel();
723
724 if (parentModel != null) {
725 final String parentGroupId = getGroupId(parentModel);
726 final String parentVersion = getVersion(parentModel);
727
728 project.setParentArtifact(repositorySystem.createProjectArtifact(
729 parentGroupId, parentModel.getArtifactId(), parentVersion));
730
731 MavenProject parent = projectIndex.get(parentModel.getId());
732 if (parent == null) {
733
734
735
736
737
738 request.setRemoteRepositories(project.getRemoteArtifactRepositories());
739 Path parentPomFile = parentModel.getPomFile();
740 if (parentPomFile != null) {
741 project.setParentFile(parentPomFile.toFile());
742 try {
743 parent = build(parentPomFile, ModelSource.fromPath(parentPomFile))
744 .getProject();
745 } catch (ProjectBuildingException e) {
746
747 if (logger.isDebugEnabled()) {
748
749 logger.warn("Failed to build parent project for " + project.getId(), e);
750 } else {
751
752 logger.warn("Failed to build parent project for " + project.getId());
753 }
754 }
755 } else {
756 Artifact parentArtifact = project.getParentArtifact();
757 try {
758 parent = build(parentArtifact, false).getProject();
759 } catch (ProjectBuildingException e) {
760
761 if (logger.isDebugEnabled()) {
762
763 logger.warn("Failed to build parent project for " + project.getId(), e);
764 } else {
765
766 logger.warn("Failed to build parent project for " + project.getId());
767 }
768 }
769 }
770 }
771 project.setParent(parent);
772 if (project.getParentFile() == null && parent != null) {
773 project.setParentFile(parent.getFile());
774 }
775 }
776 }
777
778 private ModelBuilderRequest.ModelBuilderRequestBuilder getModelBuildingRequest() {
779 ModelBuilderRequest.ModelBuilderRequestBuilder modelBuildingRequest = ModelBuilderRequest.builder();
780
781 InternalSession internalSession = InternalSession.from(session);
782 modelBuildingRequest.session(internalSession);
783 modelBuildingRequest.requestType(ModelBuilderRequest.RequestType.BUILD_PROJECT);
784 modelBuildingRequest.profiles(
785 request.getProfiles() != null
786 ? request.getProfiles().stream()
787 .map(org.apache.maven.model.Profile::getDelegate)
788 .toList()
789 : null);
790 modelBuildingRequest.activeProfileIds(request.getActiveProfileIds());
791 modelBuildingRequest.inactiveProfileIds(request.getInactiveProfileIds());
792 modelBuildingRequest.systemProperties(toMap(request.getSystemProperties()));
793 modelBuildingRequest.userProperties(toMap(request.getUserProperties()));
794 modelBuildingRequest.repositoryMerging(ModelBuilderRequest.RepositoryMerging.valueOf(
795 request.getRepositoryMerging().name()));
796 modelBuildingRequest.repositories(request.getRemoteRepositories().stream()
797 .map(r -> internalSession.getRemoteRepository(RepositoryUtils.toRepo(r)))
798 .toList());
799 return modelBuildingRequest;
800 }
801
802 private DependencyResolutionResult resolveDependencies(MavenProject project) {
803 DependencyResolutionResult resolutionResult;
804
805 try {
806 DefaultDependencyResolutionRequest resolution =
807 new DefaultDependencyResolutionRequest(project, session);
808 resolutionResult = dependencyResolver.resolve(resolution);
809 } catch (DependencyResolutionException e) {
810 resolutionResult = e.getResult();
811 }
812
813 Set<Artifact> artifacts = new LinkedHashSet<>();
814 if (resolutionResult.getDependencyGraph() != null) {
815 RepositoryUtils.toArtifacts(
816 artifacts,
817 resolutionResult.getDependencyGraph().getChildren(),
818 Collections.singletonList(project.getArtifact().getId()),
819 null);
820
821
822 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
823 for (Artifact artifact : artifacts) {
824 if (!artifact.isResolved()) {
825 String path = lrm.getPathForLocalArtifact(RepositoryUtils.toArtifact(artifact));
826 artifact.setFile(
827 lrm.getRepository().getBasePath().resolve(path).toFile());
828 }
829 }
830 }
831 project.setResolvedArtifacts(artifacts);
832 project.setArtifacts(artifacts);
833
834 return resolutionResult;
835 }
836 }
837
838 private List<String> getProfileIds(List<Profile> profiles) {
839 return profiles.stream().map(Profile::getId).collect(Collectors.toList());
840 }
841
842 private static ModelSource createStubModelSource(Artifact artifact) {
843 String xml = "<?xml version='1.0'?>" + "<project>"
844 + "<modelVersion>4.0.0</modelVersion>"
845 + "<groupId>"
846 + artifact.getGroupId() + "</groupId>" + "<artifactId>"
847 + artifact.getArtifactId() + "</artifactId>" + "<version>"
848 + artifact.getBaseVersion() + "</version>" + "<packaging>"
849 + artifact.getType() + "</packaging>" + "</project>";
850 return new StubModelSource(xml, artifact);
851 }
852
853 static String getGroupId(Model model) {
854 String groupId = model.getGroupId();
855 if (groupId == null && model.getParent() != null) {
856 groupId = model.getParent().getGroupId();
857 }
858 return groupId;
859 }
860
861 static String getVersion(Model model) {
862 String version = model.getVersion();
863 if (version == null && model.getParent() != null) {
864 version = model.getParent().getVersion();
865 }
866 return version;
867 }
868
869 private static Map<String, String> toMap(Properties properties) {
870 if (properties != null && !properties.isEmpty()) {
871 return properties.entrySet().stream()
872 .collect(Collectors.toMap(e -> String.valueOf(e.getKey()), e -> String.valueOf(e.getValue())));
873 } else {
874 return null;
875 }
876 }
877
878 static class LazyMap<K, V> extends AbstractMap<K, V> {
879 private final Supplier<Map<K, V>> supplier;
880 private volatile Map<K, V> delegate;
881
882 LazyMap(Supplier<Map<K, V>> supplier) {
883 this.supplier = supplier;
884 }
885
886 @Override
887 public Set<Entry<K, V>> entrySet() {
888 if (delegate == null) {
889 synchronized (this) {
890 if (delegate == null) {
891 delegate = supplier.get();
892 }
893 }
894 }
895 return delegate.entrySet();
896 }
897 }
898
899 private Model injectLifecycleBindings(
900 Model model,
901 ModelBuilderRequest request,
902 ModelProblemCollector problems,
903 MavenProject project,
904 ProjectBuildingRequest projectBuildingRequest) {
905 org.apache.maven.model.Model model3 = new org.apache.maven.model.Model(model);
906 List<ArtifactRepository> remoteRepositories = projectBuildingRequest.getRemoteRepositories();
907 List<ArtifactRepository> pluginRepositories = projectBuildingRequest.getPluginArtifactRepositories();
908 try {
909 pluginRepositories = projectBuildingHelper.createArtifactRepositories(
910 model3.getPluginRepositories(), pluginRepositories, projectBuildingRequest);
911 } catch (Exception e) {
912 problems.add(Severity.ERROR, Version.BASE, "Invalid plugin repository: " + e.getMessage(), e);
913 }
914 project.setPluginArtifactRepositories(pluginRepositories);
915
916 if (request.getRequestType() == ModelBuilderRequest.RequestType.BUILD_PROJECT) {
917 try {
918 ProjectRealmCache.CacheRecord record =
919 projectBuildingHelper.createProjectRealm(project, model3, projectBuildingRequest);
920
921 project.setClassRealm(record.getRealm());
922 project.setExtensionDependencyFilter(record.getExtensionArtifactFilter());
923 } catch (PluginResolutionException | PluginManagerException | PluginVersionResolutionException e) {
924
925 problems.add(Severity.ERROR, Version.BASE, "Unresolvable build extension: " + e.getMessage(), e);
926 }
927 projectBuildingHelper.selectProjectRealm(project);
928 }
929
930
931 try {
932 remoteRepositories = projectBuildingHelper.createArtifactRepositories(
933 model3.getRepositories(), remoteRepositories, projectBuildingRequest);
934 } catch (Exception e) {
935 problems.add(Severity.ERROR, Version.BASE, "Invalid artifact repository: " + e.getMessage(), e);
936 }
937 project.setRemoteArtifactRepositories(remoteRepositories);
938
939 if (projectBuildingRequest.isProcessPlugins()) {
940 return lifecycleBindingsInjector.injectLifecycleBindings(model3.getDelegate(), request, problems);
941 } else {
942 return model3.getDelegate();
943 }
944 }
945 }