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