1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.basepom.inline.mojo;
16
17 import static com.google.common.base.Preconditions.checkNotNull;
18 import static com.google.common.collect.ImmutableSet.toImmutableSet;
19
20 import java.util.List;
21 import java.util.Objects;
22
23 import com.google.common.base.Throwables;
24 import com.google.common.collect.ImmutableList;
25 import com.google.common.collect.ImmutableSet;
26 import org.apache.maven.RepositoryUtils;
27 import org.apache.maven.execution.MavenSession;
28 import org.apache.maven.project.DefaultDependencyResolutionRequest;
29 import org.apache.maven.project.DefaultProjectBuildingRequest;
30 import org.apache.maven.project.DependencyResolutionException;
31 import org.apache.maven.project.DependencyResolutionRequest;
32 import org.apache.maven.project.DependencyResolutionResult;
33 import org.apache.maven.project.MavenProject;
34 import org.apache.maven.project.ProjectBuilder;
35 import org.apache.maven.project.ProjectBuildingException;
36 import org.apache.maven.project.ProjectBuildingRequest;
37 import org.apache.maven.project.ProjectBuildingResult;
38 import org.apache.maven.project.ProjectDependenciesResolver;
39 import org.eclipse.aether.artifact.Artifact;
40 import org.eclipse.aether.artifact.DefaultArtifact;
41 import org.eclipse.aether.graph.Dependency;
42 import org.eclipse.aether.graph.DependencyFilter;
43 import org.eclipse.aether.repository.RemoteRepository;
44 import org.eclipse.aether.transfer.ArtifactTransferException;
45 import org.eclipse.aether.transfer.NoRepositoryLayoutException;
46 import org.eclipse.aether.util.artifact.JavaScopes;
47
48
49
50
51 final class DependencyBuilder {
52
53 private static final PluginLog LOG = new PluginLog(DependencyBuilder.class);
54
55 private final MavenProject rootProject;
56 private final MavenSession mavenSession;
57 private final ProjectBuilder projectBuilder;
58 private final ProjectDependenciesResolver projectDependenciesResolver;
59 private final List<MavenProject> reactorProjects;
60
61 DependencyBuilder(MavenProject rootProject, MavenSession mavenSession, ProjectBuilder projectBuilder,
62 ProjectDependenciesResolver projectDependenciesResolver, List<MavenProject> reactorProjects) {
63 this.rootProject = rootProject;
64 this.mavenSession = mavenSession;
65 this.projectBuilder = projectBuilder;
66 this.projectDependenciesResolver = projectDependenciesResolver;
67 this.reactorProjects = ImmutableList.copyOf(reactorProjects);
68 }
69
70
71
72
73
74
75
76
77
78
79 ImmutableList<Dependency> mapDependency(final Dependency dependency,
80 final DependencyFilter projectScopeFilter)
81 throws DependencyResolutionException, ProjectBuildingException {
82 checkNotNull(dependency, "dependency is null");
83
84
85 final ProjectBuildingResult result = projectBuilder.build(convertFromAetherDependency(dependency), false, createProjectBuildingRequest());
86
87
88 final MavenProject project = result.getProject();
89 return mapProject(project, projectScopeFilter);
90 }
91
92
93
94
95
96
97
98
99
100 ImmutableList<Dependency> mapProject(final MavenProject project,
101 final DependencyFilter scopeFilter)
102 throws DependencyResolutionException {
103 checkNotNull(project, "project is null");
104
105 final DependencyResolutionRequest request = new DefaultDependencyResolutionRequest();
106 request.setRepositorySession(createProjectBuildingRequest().getRepositorySession());
107 request.setMavenProject(project);
108 request.setResolutionFilter(scopeFilter);
109
110 DependencyResolutionResult result;
111
112 try {
113 result = projectDependenciesResolver.resolve(request);
114 } catch (DependencyResolutionException e) {
115 result = e.getResult();
116
117 final ImmutableSet<ProjectKey> reactorProjects = this.reactorProjects.stream()
118 .map(ProjectKey::fromProject).collect(toImmutableSet());
119
120
121 final ImmutableSet<Dependency> reactorDependencies = result.getUnresolvedDependencies().stream()
122 .filter(d -> reactorProjects.contains(ProjectKey.fromDependency(d)))
123 .collect(toImmutableSet());
124
125 result.getUnresolvedDependencies().removeAll(reactorDependencies);
126 result.getResolvedDependencies().addAll(reactorDependencies);
127
128
129 final ImmutableSet<Dependency> systemDependencies = result.getUnresolvedDependencies().stream()
130 .filter(d -> JavaScopes.SYSTEM.equals(d.getScope()))
131 .collect(toImmutableSet());
132
133 result.getUnresolvedDependencies().removeAll(systemDependencies);
134 result.getResolvedDependencies().addAll(systemDependencies);
135
136
137 final ImmutableSet<Dependency> optionalDependencies = result.getUnresolvedDependencies().stream()
138 .filter(Dependency::isOptional)
139 .collect(toImmutableSet());
140
141 result.getUnresolvedDependencies().removeAll(optionalDependencies);
142 result.getResolvedDependencies().addAll(optionalDependencies);
143
144 if (!result.getUnresolvedDependencies().isEmpty()) {
145 final Throwable t = Throwables.getRootCause(e);
146 RemoteRepository repository = null;
147
148 if (t instanceof NoRepositoryLayoutException) {
149 repository = ((NoRepositoryLayoutException) t).getRepository();
150 } else if (t instanceof ArtifactTransferException) {
151 repository = ((ArtifactTransferException) t).getRepository();
152 }
153
154 if (repository != null && "legacy".equals(repository.getContentType())) {
155 LOG.warn("Could not access a legacy repository for artifacts: %s; Reason: %s", result.getUnresolvedDependencies(), t.getMessage());
156 } else {
157 throw e;
158 }
159 }
160 }
161
162 return ImmutableList.copyOf(result.getResolvedDependencies());
163 }
164
165 static org.apache.maven.artifact.Artifact convertFromAetherDependency(final Dependency dependency) {
166 final var mavenArtifact = RepositoryUtils.toArtifact(convertToPomArtifact(dependency.getArtifact()));
167 mavenArtifact.setScope(dependency.getScope());
168 mavenArtifact.setOptional(dependency.isOptional());
169
170 return mavenArtifact;
171 }
172
173 private ProjectBuildingRequest createProjectBuildingRequest() {
174 DefaultProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(mavenSession.getProjectBuildingRequest());
175 buildingRequest.setRemoteRepositories(rootProject.getRemoteArtifactRepositories());
176 return buildingRequest;
177 }
178
179
180 static Artifact convertToPomArtifact(final Artifact artifact) {
181
182 if (artifact.getClassifier().isEmpty() && "pom".equals(artifact.getExtension())) {
183 return artifact;
184 }
185
186
187 return new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), "pom", artifact.getVersion());
188 }
189
190 private static final class ProjectKey {
191
192 private final String groupId;
193 private final String artifactId;
194 private final String version;
195
196 public static ProjectKey fromProject(final MavenProject project) {
197 checkNotNull(project, "project; is null");
198 return new ProjectKey(project.getGroupId(), project.getArtifactId(), project.getVersion());
199 }
200
201 public static ProjectKey fromDependency(final Dependency dependency) {
202 checkNotNull(dependency, "artifact; is null");
203 return new ProjectKey(dependency.getArtifact().getGroupId(),
204 dependency.getArtifact().getArtifactId(),
205 dependency.getArtifact().getVersion());
206 }
207
208 private ProjectKey(final String groupId, final String artifactId, final String version) {
209 this.groupId = checkNotNull(groupId, "groupId is null");
210 this.artifactId = checkNotNull(artifactId, "artifactId is null");
211 this.version = checkNotNull(version, "version is null");
212 }
213
214 @Override
215 public boolean equals(Object o) {
216 if (this == o) {
217 return true;
218 }
219 if (o == null || getClass() != o.getClass()) {
220 return false;
221 }
222 ProjectKey that = (ProjectKey) o;
223 return groupId.equals(that.groupId)
224 && artifactId.equals(that.artifactId)
225 && version.equals(that.version);
226 }
227
228 @Override
229 public int hashCode() {
230 return Objects.hash(groupId, artifactId, version);
231 }
232 }
233 }