1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.dependency;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Enumeration;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.jar.JarEntry;
27 import java.util.jar.JarFile;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30 import org.apache.maven.artifact.handler.ArtifactHandler;
31 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
32 import org.apache.maven.artifact.repository.ArtifactRepository;
33 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
34 import org.apache.maven.artifact.repository.MavenArtifactRepository;
35 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
36 import org.apache.maven.execution.MavenSession;
37 import org.apache.maven.plugin.AbstractMojo;
38 import org.apache.maven.plugin.MojoExecutionException;
39 import org.apache.maven.plugin.MojoFailureException;
40 import org.apache.maven.plugins.annotations.Component;
41 import org.apache.maven.plugins.annotations.Mojo;
42 import org.apache.maven.plugins.annotations.Parameter;
43 import org.apache.maven.project.DefaultProjectBuildingRequest;
44 import org.apache.maven.project.ProjectBuildingRequest;
45 import org.apache.maven.repository.RepositorySystem;
46 import org.apache.maven.settings.Settings;
47 import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
48 import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate;
49 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
50 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
51 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
52 import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate;
53 import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
54 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
55 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
56
57
58
59
60 @Mojo(name = "list-classes", requiresProject = false, threadSafe = true)
61 public class ListClassesMojo extends AbstractMojo {
62 private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile("(.+)::(.*)::(.+)");
63
64 @Parameter(defaultValue = "${session}", required = true, readonly = true)
65 private MavenSession session;
66
67 @Component
68 private ArtifactResolver artifactResolver;
69
70 @Component
71 private DependencyResolver dependencyResolver;
72
73 @Component
74 private ArtifactHandlerManager artifactHandlerManager;
75
76
77
78
79 @Component(role = ArtifactRepositoryLayout.class)
80 private Map<String, ArtifactRepositoryLayout> repositoryLayouts;
81
82
83
84
85 @Component
86 private RepositorySystem repositorySystem;
87
88 private DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate();
89
90
91
92
93 @Parameter(property = "groupId")
94 private String groupId;
95
96
97
98
99 @Parameter(property = "artifactId")
100 private String artifactId;
101
102
103
104
105 @Parameter(property = "version")
106 private String version;
107
108
109
110
111
112
113 @Parameter(property = "classifier")
114 private String classifier;
115
116
117
118
119 @Parameter(property = "packaging", defaultValue = "jar")
120 private String packaging = "jar";
121
122
123
124
125
126 @Parameter(property = "remoteRepositories")
127 private String remoteRepositories;
128
129
130
131
132 @Parameter(property = "artifact")
133 private String artifact;
134
135 @Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true)
136 private List<ArtifactRepository> pomRemoteRepositories;
137
138
139
140
141 @Parameter(property = "transitive", defaultValue = "false")
142 private boolean transitive = false;
143
144
145
146
147 @Parameter(property = "mdep.skip", defaultValue = "false")
148 private boolean skip;
149
150 @Override
151 public void execute() throws MojoExecutionException, MojoFailureException {
152 ProjectBuildingRequest buildingRequest = makeBuildingRequest();
153
154 try {
155 if (transitive) {
156 Iterable<ArtifactResult> artifacts =
157 dependencyResolver.resolveDependencies(buildingRequest, coordinate, null);
158
159 for (ArtifactResult result : artifacts) {
160 printClassesFromArtifactResult(result);
161 }
162 } else {
163 ArtifactResult result =
164 artifactResolver.resolveArtifact(buildingRequest, toArtifactCoordinate(coordinate));
165
166 printClassesFromArtifactResult(result);
167 }
168 } catch (ArtifactResolverException | DependencyResolverException | IOException e) {
169 throw new MojoExecutionException("Couldn't download artifact: " + e.getMessage(), e);
170 }
171 }
172
173 private void printClassesFromArtifactResult(ArtifactResult result) throws IOException {
174
175 try (JarFile jarFile = new JarFile(result.getArtifact().getFile())) {
176 Enumeration<JarEntry> entries = jarFile.entries();
177
178 while (entries.hasMoreElements()) {
179 JarEntry entry = entries.nextElement();
180 String entryName = entry.getName();
181
182
183 if (!entryName.endsWith(".class")) {
184 continue;
185 }
186
187
188 String className =
189 entryName.substring(0, entryName.length() - 6).replace('/', '.');
190 getLog().info(className);
191 }
192 }
193 }
194
195 private ProjectBuildingRequest makeBuildingRequest() throws MojoExecutionException, MojoFailureException {
196 if (artifact == null) {
197 throw new MojoFailureException("You must specify an artifact, "
198 + "e.g. -Dartifact=org.apache.maven.plugins:maven-downloader-plugin:1.0");
199 }
200
201 String[] tokens = artifact.split(":");
202 if (tokens.length < 3 || tokens.length > 5) {
203 throw new MojoFailureException("Invalid artifact, you must specify "
204 + "groupId:artifactId:version[:packaging[:classifier]] " + artifact);
205 }
206 coordinate.setGroupId(tokens[0]);
207 coordinate.setArtifactId(tokens[1]);
208 coordinate.setVersion(tokens[2]);
209 if (tokens.length >= 4) {
210 coordinate.setType(tokens[3]);
211 }
212 if (tokens.length == 5) {
213 coordinate.setClassifier(tokens[4]);
214 }
215
216 ArtifactRepositoryPolicy always = new ArtifactRepositoryPolicy(
217 true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN);
218
219 List<ArtifactRepository> repoList = new ArrayList<>();
220
221 if (pomRemoteRepositories != null) {
222 repoList.addAll(pomRemoteRepositories);
223 }
224
225 if (remoteRepositories != null) {
226
227 String[] repos = remoteRepositories.split(",");
228 for (String repo : repos) {
229 repoList.add(parseRepository(repo, always));
230 }
231 }
232
233 ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
234
235 Settings settings = session.getSettings();
236 repositorySystem.injectMirror(repoList, settings.getMirrors());
237 repositorySystem.injectProxy(repoList, settings.getProxies());
238 repositorySystem.injectAuthentication(repoList, settings.getServers());
239
240 buildingRequest.setRemoteRepositories(repoList);
241
242 return buildingRequest;
243 }
244
245 private ArtifactCoordinate toArtifactCoordinate(DependableCoordinate dependableCoordinate) {
246 ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler(dependableCoordinate.getType());
247 DefaultArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate();
248 artifactCoordinate.setGroupId(dependableCoordinate.getGroupId());
249 artifactCoordinate.setArtifactId(dependableCoordinate.getArtifactId());
250 artifactCoordinate.setVersion(dependableCoordinate.getVersion());
251 artifactCoordinate.setClassifier(dependableCoordinate.getClassifier());
252 artifactCoordinate.setExtension(artifactHandler.getExtension());
253 return artifactCoordinate;
254 }
255
256 protected ArtifactRepository parseRepository(String repo, ArtifactRepositoryPolicy policy)
257 throws MojoFailureException {
258
259 String id = "temp";
260 ArtifactRepositoryLayout layout = getLayout("default");
261
262
263 if (repo.contains("::")) {
264 Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher(repo);
265 if (!matcher.matches()) {
266 throw new MojoFailureException(
267 repo,
268 "Invalid syntax for repository: " + repo,
269 "Invalid syntax for repository. Use \"id::layout::url\" or \"URL\".");
270 }
271
272 id = matcher.group(1).trim();
273 if (!(matcher.group(2) == null || matcher.group(2).trim().isEmpty())) {
274 layout = getLayout(matcher.group(2).trim());
275 }
276 repo = matcher.group(3).trim();
277 }
278 return new MavenArtifactRepository(id, repo, layout, policy, policy);
279 }
280
281 private ArtifactRepositoryLayout getLayout(String id) throws MojoFailureException {
282 ArtifactRepositoryLayout layout = repositoryLayouts.get(id);
283
284 if (layout == null) {
285 throw new MojoFailureException(id, "Invalid repository layout", "Invalid repository layout: " + id);
286 }
287
288 return layout;
289 }
290 }