forked from jetty/jetty.project
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MavenProjectHelper.java
185 lines (170 loc) · 6.69 KB
/
MavenProjectHelper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.maven.plugin.utils;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.maven.RepositoryUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.jetty.maven.plugin.OverlayManager;
import org.eclipse.jetty.maven.plugin.WarPluginInfo;
/**
* MavenProjectHelper
*
* A class to facilitate interacting with the build time maven environment.
*
*/
public class MavenProjectHelper
{
private MavenProject project;
private RepositorySystem repositorySystem;
private List<ArtifactRepository> remoteRepositories;
private MavenSession session;
private final Map<String, MavenProject> artifactToReactorProjectMap;
/**
* maven-war-plugin reference
*/
private WarPluginInfo warPluginInfo;
/**
* Helper for wrangling war overlays
*/
private OverlayManager overlayManager;
/**
* @param project the project being built
* @param repositorySystem a resolve for artifacts
* @param remoteRepositories repositories from which to resolve artifacts
* @param session the current maven build session
*/
public MavenProjectHelper(MavenProject project, RepositorySystem repositorySystem, List<ArtifactRepository> remoteRepositories, MavenSession session)
{
this.project = project;
this.repositorySystem = repositorySystem;
this.remoteRepositories = remoteRepositories;
this.session = session;
//work out which dependent projects are in the reactor
Set<MavenProject> mavenProjects = findDependenciesInReactor(project, new HashSet<>());
artifactToReactorProjectMap = mavenProjects.stream()
.collect(Collectors.toMap(MavenProject::getId, Function.identity()));
artifactToReactorProjectMap.put(project.getArtifact().getId(), project);
warPluginInfo = new WarPluginInfo(project);
overlayManager = new OverlayManager(warPluginInfo);
}
public MavenProject getProject()
{
return this.project;
}
public WarPluginInfo getWarPluginInfo()
{
return warPluginInfo;
}
public OverlayManager getOverlayManager()
{
return overlayManager;
}
/**
* Gets the maven project represented by the artifact iff it is in
* the reactor.
*
* @param artifact the artifact of the project to get
* @return {@link MavenProject} if artifact is referenced in reactor, otherwise null
*/
public MavenProject getMavenProjectFor(Artifact artifact)
{
return artifactToReactorProjectMap.get(artifact.getId());
}
/**
* Gets path to artifact.
* If the artifact is referenced in the reactor, returns path to ${project.build.outputDirectory}.
* Otherwise, returns path to location in local m2 repo.
*
* Cannot return null - maven will complain about unsatisfied dependency during project build.
*
* @param artifact maven artifact to check
* @return path to artifact
*/
public Path getPathFor(Artifact artifact)
{
Path path = artifact.getFile().toPath();
MavenProject mavenProject = getMavenProjectFor(artifact);
if (mavenProject != null)
{
if ("test-jar".equals(artifact.getType()))
{
path = Paths.get(mavenProject.getBuild().getTestOutputDirectory());
}
else
{
path = Paths.get(mavenProject.getBuild().getOutputDirectory());
}
}
return path;
}
/**
* Given the coordinates for an artifact, resolve the artifact from the
* remote repositories.
*
* @param groupId the groupId of the artifact to resolve
* @param artifactId the artifactId of the artifact to resolve
* @param version the version of the artifact to resolve
* @param type the type of the artifact to resolve
* @return a File representing the location of the artifact or null if not resolved
* @throws ArtifactResolutionException
*/
public File resolveArtifact(String groupId, String artifactId, String version, String type)
throws ArtifactResolutionException
{
ArtifactRequest request = new ArtifactRequest();
request.setRepositories(RepositoryUtils.toRepos(remoteRepositories));
request.setArtifact(new DefaultArtifact(groupId, artifactId, "", type, version));
ArtifactResult result = repositorySystem.resolveArtifact(session.getRepositorySession(), request);
if (result.isResolved())
return result.getArtifact().getFile();
return null;
}
/**
* Recursively find projects in the reactor for all dependencies of the given project.
*
* @param project the project for which to find dependencies that are in the reactor
* @param visitedProjects the set of projects already seen
* @return unified set of all related projects in the reactor
*/
private static Set<MavenProject> findDependenciesInReactor(MavenProject project, Set<MavenProject> visitedProjects)
{
if (visitedProjects.contains(project))
return Collections.emptySet();
visitedProjects.add(project);
Collection<MavenProject> refs = project.getProjectReferences().values();
Set<MavenProject> availableProjects = new HashSet<>(refs);
for (MavenProject ref : refs)
{
availableProjects.addAll(findDependenciesInReactor(ref, visitedProjects));
}
return availableProjects;
}
}